elfenliedtopfan5 Ответов: 1

Rip изображения сложного HTML файла с использованием регулярных выражений


хорошо проблемы с которыми я сталкиваюсь здесь они не находятся в комментарии href или src это сниплет кода который я хочу получить но я также хочу получить его по размеру так же как и все изображения которые 2048 x 2048 одинаковы с 4065 x 4065

<pre>#34;, "createdAt": "2018-07-30T13:33:21.373947"}, {"uid": "c442c352934545b183e16ce9aebd91cb", "width": 2048, "options": {"format": "R", "quality": 88}, "updatedAt": "2018-08-01T17:51:24.738232", "height": 2048, "size": 618478, "url": "https://media.sketchfab.com/urls/ea1adc30399045a2b101e16ba65a856f/dist/textures/a4291782af5f4ce39e637c89ec91fa9b/c442c352934545b183e16ce9aebd91cb.jpeg", "createdAt": "2018-08-01T17:51:25.334608"}, {"uid": "84275b9d01b54836893e355991288c2f", "width": 1024, "options": {"format": "R", "quality": 92}, "updatedAt": "2018-08-01T17:51:25.341010", "height": 1024, "size": 220485, "url": "https://media.sketchfab.com/urls/ea1adc30399045a2b101e16ba65a856f/dist/textures/a4291782af5f4ce39e637c89ec91fa9b/84275b9d01b54836893e355991288c2f.jpeg", "createdAt": "2018-08-01T17:51:25.451079"}, {"uid": "88897653dc004ded9faee4eaf2fa0373", "width": 512, "options": {"format": "R", "quality": 95}, "updatedAt": "2018-08-01T17:51:25.456671", "height": 512, "size": 83896, "url": "https://media.sketchfab.com/urls/ea1adc30399045a2b101e16ba65a856f/dist/textures/a4291782af5f4ce39e637c89ec91fa9b/88897653dc004ded9faee4eaf2fa0373.jpeg"



то, что я хочу сделать, это проверить С и высота, и если он соответствует 2048 x2048, то точно это изображение и сохранить в папку же с 4096 x 4096

мне удалось сделать регулярное выражение для длинной ссылки
(https://media.sketchfab.com)/urls/[a-z0-9]+/dist/textures/[a-z0-9]+/[a-z0-9]+.jpeg


но не знаю как заставить его скачать все изображения в зависимости от размера если бы кто нибудь мог помочь был бы очень удивлен действительно отстой в этом заранее спасибо elfenliedtopfan5

Что я уже пробовал:

(https://media.sketchfab.com)/urls/[a-z0-9]+/dist/textures/[a-z0-9]+/[a-z0-9]+.jpeg


string urlAddress = "https://sketchfab.com/3d-models/mossberg-590-tactical-ea1adc30399045a2b101e16ba65a856f";
string urlBase = "https://sketchfab.com";

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlAddress);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string data = "";
if (response.StatusCode == HttpStatusCode.OK)
{
    Stream receiveStream = response.GetResponseStream();
    StreamReader readStream = null;
    if (response.CharacterSet == null)
        readStream = new StreamReader(receiveStream);
    else
        readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
    data = readStream.ReadToEnd();
    response.Close();
    readStream.Close();
}
MatchCollection matches = Regex.Matches(data, @"(https://media.sketchfab.com)/urls/[a-z0-9]+/dist/textures/[a-z0-9]+/[a-z0-9]+.jpeg");
for (int a = 0; a < matches.Count; a++)
    MessageBox.Show(urlBase + matches[a].Groups["link"].Value);

DerekT-P

У вас есть данные JSON; зачем использовать регулярное выражение для разбора этого, а не просто разбор JSON (google JSON.Net) ... ?

phil.o

Вы должны опубликовать решение из этого совета и взять на себя ответственность за него.

1 Ответов

Рейтинг:
2

lmoelleb

Как сказал Деректп123, не используйте для этого регулярное выражение. Работайте с объектом JSON - у вас есть ширина, высота и URL-адрес именно так, как вам нужно. это сделает код более простым для чтения, более легким в обслуживании и менее подверженным ошибкам.

Конечно, вам придется научиться иметь дело с JSON, но поскольку JSON есть везде - вы можете также изучить его и получить преимущества сразу же.
Самая популярная библиотека-это JSON.NET - поэтому я рекомендую вам придерживаться этого, так как вы найдете большинство примеров, использующих это. Microsoft также использует его.

Google что-то вроде: Json.Чистый учебник.

В общем случае у вас есть два варианта - написать объект C#, представляющий JSON, и иметь JSON.NET заполните его. Сначала нужно немного больше печатать, но потом он становится простым в использовании. Увидеть больше здесь[^].

Кроме того, вы можете прочитать объект как JsonObject. Затем вы должны сами индексировать все свойства. Вам не понадобятся никакие классы C#, представляющие json, но вам придется убедиться, что вы вводите правильные имена свойств при его использовании - компилятор вам не поможет. Примеры здесь[^].

Если - как вы упомянули в комментарии - получить доступ к JSON по той или иной причине нелегко, можно написать регулярное выражение, просто будьте готовы регулярно возиться с ним, чтобы он продолжал работать.

Я создал пример, который, кажется, работает:

"width"\s*:\s*(?'width'\d+).+?"height"\s*:\s*(?'height'\d+).+?"url"\s*:\s*\"(?'url'.+?)"

Он полагается на порядок свойств в объекте json - то, что вы действительно не должны делать, поскольку порядок свойств не имеет значения в json - то есть код, пишущий его, может изменить его без видимой причины, - но нелегко написать простое регулярное выражение, которое может обрабатывать переупорядочение.

Регулярное выражение довольно прямолинейно, как и обычные выражения. Сначала он ищет "width", двоеточие (с необязательным пробелом вокруг него), за которым следует именованная группа подписей "ширина", принимающая следующие цифры. То ?'width' только внутри круглой скобки определяется имя. В этом нет необходимости, но это облегчает извлечение значений позже надежным способом - поскольку будущие изменения могут добавить дополнительные группы (группа-это все, что угодно в скобках).

Затем он пропускает до тех пор, пока "height" который захватывается таким же образом. Обратите внимание, что пропуск других свойств json выполняется с помощью .+?. Перемещение ? говорит регулярному выражению "остановиться" при первой же возможности (так что в первый раз оно может совпадать "height" Без этого регулярное выражение "жадно" - поэтому оно будет соответствовать столько, сколько сможет. Это заставит его прочитать первую ширину в вашем тексте, а затем пропустить весь путь до последней высоты - и вы получите только одно совпадение.

Наконец он перескакивает на "url" и создает новую группу, захватывая текст внутри следующих цитат - опять же используя не жадное совпадение, чтобы убедиться, что оно остановится на первой цитате, а не съест весь ваш текст за один раз.

Вы можете играть с тем, чтобы сделать его более ограничительным, чтобы избежать ложных срабатываний, конечно. Я рекомендую вам использовать онлайн-валидатор, чтобы быстро увидеть результат ваших изменений, возможно, что-то вроде regex101.com[^]

Как только у вас есть URL-адрес, вы можете легко загрузить изображение (до тех пор, пока сайт не попытается остановить вас).

Я рекомендую вам посмотреть на служба WebClient[^]

В частности, методы OpenRead, DownloadData и DownloadFile. Вы можете использовать любой из них, но в зависимости от того, что вы хотите сделать с изображением, один из них, скорее всего, предложит более удобный выход, чем два других. Вы также можете заменить HttpWebRequest/HttpWebResponse на WebClient. Он будет делать ВСЮ работу, читая поток ответов для вас (в основном он просто обертывает HttpWebRequest/Response и будет делать все скучные вещи для вас).


elfenliedtopfan5

да, я вчера заглянул в json, но проблема в том, что есть около 30 случаев этого на html-сайте, и с json вы должны поставить id : "sometexthere", и проблема в том, что я не знаю, что это за имена, потому что они хэшируются, поэтому я не уверен, как правильно это сделать.

lmoelleb

Я добавил пример регулярного выражения - включенную ссылку на regex101.com он приведет вас на сайт, где он уже заполнен, что позволит вам легко играть с ним.

elfenliedtopfan5

МММ это здорово только проблема у меня есть это дает мне кучу ошибок из-за форматирования регулярного выражения я думаю, как \ ? ошибка

lmoelleb

Я нажимаю на ссылку regex101 и не вижу никаких ошибок. Где вы видите ошибки, и что это за ошибки. Пожалуйста, никогда не сообщайте о чем-то вроде "загрузки ошибок", Всегда включайте хотя бы один точный пример того, что такое текст ошибки и где вы его видите. Регулярное выражение содержит " и \, которые должны быть экранированы, когда вы копируете его в виде строки в свой исходный код c# - это проблема? Я не могу сказать наверняка без точной информации.

elfenliedtopfan5

Извините за отсутствие информации, это было действительно рано утром прошлой ночью, так что в основном да, когда я скопировал его на c# в качестве Паттена, я получил ошибки на \s ? но я предполагаю, что это потому, что его цитируют, и там \ я думаю, что-то означает и в c#

но с чертовски большим количеством редактирования мне удалось придумать это

@"""ширина""и\S*:\с*(?'ширина'и\D+).+?""высота""и\S*:\С*(?'высота'и\D+).+?""адрес URL""\с*:\с*\""(?'URL-адрес'.+?)"""

но регулярное выражение все равно просто пропускает найденную часть совпадения
https://i.imgur.com/SDJsYff.gifv

lmoelleb

Так что поиск замены "-> " - Это чертовски много редактирования-у меня есть некоторые плохие новости о том, насколько просто это редактирование в контексте программирования. :)

Did you look careful at the source text? Copy paste it from the debugger into regex101 and check it match. When I look at the source from the website, I find HTML escaped text. So it is not "width". It seems code project is automatically adjusting the text we write, hence the example in your post no longer match the source). So either change HTML decode the source first, or adjust the regex to match " instead of ". Regex101 can help you with this - just copy the source text over, start building up the regex based on my example. Do NOT copy over the entire regex, type from the start and see the match changing as you go. If you copy all at once, nothing will match and you can't see when you make the regex either better or worse.

elfenliedtopfan5

я скачал сорс веб-страницы, я просто не могу найти правильный foumla, и что вы имеете в виду, что мой код автоматически подстраивает текст ?

lmoelleb

Copy the source text of the web page from the debugger and paste it into the Test String field on regex191.com. Now start typing the regex. Observe how regex101.com will show you what is matched. Hover the mouse over the colored parts of the regex, and it will give you a sentence telling you what it matches. If you just keep trying stuff in C# you will never get it right. If you are not willing to use regex101.com or a similar tool, then regex is not for you, and you should write the code with IndexOf and Substring etc. Once you have it working on regex101, move it to C# (making sure to escape it as you did earlier). Still can't figure it out, google "regex tutorial" - there are tons of them. If all you want is someone to supply you the regex, then you are better of avoid regexes in that case. They are useful, but you need to invest time in learning how to use them.

elfenliedtopfan5

хорошо, мне удалось заставить его работать и скачать, но единственная проблема, которая у меня сейчас есть, это способ сделать это с помощью блочного кода, так как это все одно, когда он называет текстуры, они не соответствуют правильному имени, так что есть ли способ получить имя с высотой, а затем url, а затем повторно делать это каждый раз ?

lmoelleb

Отличный. Для выполнения этого блока за блоком это выходит за рамки того, что вы сделали бы с одним регулярным выражением. Выполните цикл над блоками, а затем используйте свое регулярное выражение с текстом каждого блока. Вы можете использовать другое регулярное выражение для идентификации блоков - или часто строки.IndexOf и string.Подстрока подойдет.