Найти - Пользователи
Полная версия: Проблема с парсингом Бинг
Начало » Python для новичков » Проблема с парсингом Бинг
1 2
Stargazer
Доброго времени суток. Недавно начал изучать Пайтон. В качестве практики решил написать простой парсер выдачи Bing. Но столкнулся с проблемой.

Итак, мой код выглядит вот так:

 from requests_html import HTMLSession
keywords = [
'как сделать бумажный самолетик',
'как сделать бумажный кораблик',
'как сделать бумажного журавля'
]
session = HTMLSession()
for key in keywords:
    resp = session.get(f'https://www.bing.com/search?q={key}')
    title = resp.html.xpath('//li[@class="b_algo"][1]//h2//text()')
    print(title)

Открываю сессию. В цикле получаю выдачу для каждого из трех ключей и с помощью xpath забираю ТОП-1 выдачи. После этого печатаю результат в консоль.

При этом получаю вот такой результат:
 []
['6 лучших схем бумажных корабликов - Поделки из бумаги']
['Как сложить бумажного журавлика (с иллюстрациями)']

Результата по запросу “как сделать бумажный самолетик” нет. Остальные запросы - ОК.

Если распечатать в файл весь html код страницы, которую парсер получает по первому запросу (файл прилагается) в h1 находиться фраза “Не удалось найти ни одного результата для как сделать бумажный самолетик”.

При этом если зайти по этому адресу из браузера, все впорядке. Результаты показываются.

Подскажите, в чем может быть проблема?
py.user.next
Stargazer
При этом получаю вот такой результат:
В XPath-запросе указан класс b_algo и тег h2. В файле фраза находится теге li класса b_no и теге h1.

Так что под строкой
  
title = resp.html.xpath('//li[@class="b_algo"][1]//h2//text()')
тебе надо вставить проверку на пустой список. Если он пуст, то надо искать фразу li класса b_no и в теге h1, чтобы убедиться, что она там есть.
Когда ты определил, найден результат/не найден результат/произошла ошибка поиска, ты вставляешь строку в структуру данных для вывода и эту структуру данных для вывода выводишь на экран. Соответственно, твоя структура данных для вывода заполнена тобой, а не текстом со страницы, которого может и не быть, и поэтому на экран всегда выводится всё правильно.

То есть твоя проблема в том, что ты решил код записать кратенько, типа ты профессионал и короткие коды пишешь, а в итоге тебе его теперь надо разделять и работать с ним очень подробно, чтобы код, действительно, правильно написать для начала. Так что не гонись за краткостью, это ничем тебе не поможет. Краткость рождается из длиннющих кодов. Ты сначала пишешь длиннющий код, а потом, когда он готов и отлажен 100500 раз, ты его рефакторишь в краткий код, но который точно такой же по функциональности, как и этот длиннющий. И тогда получается профессиональный код. Но для этого нужно пройти кучу длиннющих кодов и иметь в них кучу опыта, потому что их тоже можно писать совсем не правильно.
Stargazer
py.user.next
Когда ты определил, найден результат/не найден результат/произошла ошибка поиска, ты вставляешь строку в структуру данных для вывода и эту структуру данных для вывода выводишь на экран. Соответственно, твоя структура данных для вывода заполнена тобой, а не текстом со страницы, которого может и не быть, и поэтому на экран всегда выводится всё правильно.

Да, это можно сделать, но мой основной вопрос не в этом.

Я не могу понять почему по одному и тому же адресу - https://www.bing.com/search?q=как+сделать+бумажный+самолетик - браузер получает один html код, а python совершенно другой?
ZerG
Вам нужно понять что вы делаете. И потом сравнить результаты.
Что вы спросили- в питоне - то и получили. браузер имеет ряд других ключей значений и так далее.
Залезьте немного глубже в кроличью нору. Вы на правильном пути.
py.user.next
Stargazer
Я не могу понять почему по одному и тому же адресу - https://www.bing.com/search?q=как+сделать+бумажный+самолетик - браузер получает один html код, а python совершенно другой?
Потому что в браузере ещё работает движок JavaScript. И когда ты загружаешь страницу, на странице есть не только текст, но и указания для браузеров загружать и запускать внутри себя определённые скрипты. А эти скрипты имеют полный доступ к документу, который и отображается браузером у тебя в итоге. То есть не страница отображается, которую ты скачал, а всё вместе собирается в единый документ в оперативной памяти, который потом и отображается. Соответственно, что-то берётся из исходника страницы, что-то устанавливается скриптами. Поэтому на странице могут быть поля пустыми, а в браузере будет показывать текст в этих полях.

Но это всё не относится к твоей проблеме парсинга. У тебя, когда результат не найден и для его вывода используются другие теги, ты пытаешься его разобрать как найденный результат по тегам найденного результата.
Stargazer
py.user.next
У тебя, когда результат не найден и для его вывода используются другие теги, ты пытаешься его разобрать как найденный результат по тегам найденного результата.

Не могу понять. Поясни пожалуйста.
py.user.next
Stargazer
py.user.next
У тебя, когда результат не найден и для его вывода используются другие теги, ты пытаешься его разобрать как найденный результат по тегам найденного результата.
Не могу понять. Поясни пожалуйста.
Вот твой XPath-запрос
Stargazer
  
title = resp.html.xpath('//li[@class="b_algo"][1]//h2//text()')
Вот твой файл с ненайденными результатами
https://python.su/forum/attachment/4743760b048605a93010a0767175095272d1d5b0/

А теперь найди в этом файле b_algo, h2 и текст внутри h2.
Stargazer
py.user.next
А теперь найди в этом файле b_algo, h2 и текст внутри h2

Дак его там и нет. В этом то и вопрос. Питон получает html в котором нет результатов выдачи. А браузер получает по этому же запросу код с выдачей.

При этом, результаты двух других запросов в браузере и питоне совпадают. Я пытаюсь понять почему так.

Проблема в Java Script? Но библиотека html-requests насколько я понимаю поддерживает работу с JS. Только я не пойму как эту поддержку реализовать. На главной странице библиотеки https://requests-html.kennethreitz.org/ есть пример кода:

 >>> r = session.get('http://python-requests.org/')
>>> r.html.render()
>>> r.html.search('Python 2 will retire in only {months} months!')['months']
'<time>25</time>'

Получается мне нужно добавить resp.html.render() к запросу. Я попробовал, но это не помогает. Что я делаю не так?
py.user.next
Stargazer
Дак его там и нет. В этом то и вопрос. Питон получает html в котором нет результатов выдачи. А браузер получает по этому же запросу код с выдачей.
Попробовал это сделать. Вот как говорил здесь, так оно и обстоит.

  
#!/usr/bin/env python3
 
from requests_html import HTMLSession
 
keywords = [
    'как сделать бумажный самолетик',
    'как сделать бумажный кораблик',
    'как сделать бумажного журавля'
]
 
session = HTMLSession()
for key in keywords:
    resp = session.get(f'https://www.bing.com/search?q={key}')
    search_result = resp.html.xpath('//li[@class="b_algo"][1]//h2//text()')
    if search_result:
        nodes = [i.encode('latin1').decode('utf-8') for i in search_result]
        result = (True, ''.join(nodes))
    else:
        nodes = resp.html.xpath('//li[@class="b_no"][1]//h1//text()')
        result = (False, ''.join(nodes))
    status, title = result
    fmt = 'Result: {:4} Request: {}\n    {}'
    print(fmt.format(('FAIL', 'OK')[status], key, title))
[guest@localhost bingsearch]$ ./bingsearch.py 
Result: FAIL Request: как сделать бумажный самолетик
Не удалось найти ни одного результата для как сделать бумажный самолетик
Result: OK Request: как сделать бумажный кораблик
Кораблик из бумаги: 10 вариантов, 120 фото как сделать ...
Result: OK Request: как сделать бумажного журавля
Как сложить бумажного журавлика (с иллюстрациями)
[guest@localhost bingsearch]$
py.user.next
Добавив печенье, которое я взял из браузера, я получил найденные результаты.
  
#!/usr/bin/env python3
 
from requests_html import HTMLSession
 
keywords = [
    'как сделать бумажный самолетик',
    'как сделать бумажный кораблик',
    'как сделать бумажного журавля'
]
 
session = HTMLSession()
for key in keywords:
    cookie = ('_EDGE_S=F=1&SID=28A75AD8CBCA62A8303855E9CA1863C3;'
              ' _EDGE_V=1; MUID=29136B8A85066B00244864BB84D46AA3; '
              'SRCHD=AF=NOFORM; '
              'SRCHUID=V=2&GUID=C0FFD0A5EA3A49BB9F70BDDD40C53F2D&dmnchg=1; '
              'SRCHUSR=DOB=20200825; '
              '_SS=SID=28A75AD8CBCA62A8303855E9CA1863C3; '
              '_HPVN=CS=eyJQbiI6eyJDbiI6MSwiU3QiOjAsIlFzIjowLCJQcm9kIjoiUC'
              'J9LCJTYyI6eyJDbiI6MSwiU3QiOjAsIlFzIjowLCJQcm9kIjoiSCJ9LCJRe'
              'iI6eyJDbiI6MSwiU3QiOjAsIlFzIjowLCJQcm9kIjoiVCJ9LCJBcCI6dHJ1'
              'ZSwiTXV0ZSI6dHJ1ZSwiTGFkIjoiMjAyMC0wOC0yNVQwMDowMDowMFoiLCJ'
              'Jb3RkIjowLCJEZnQiOm51bGwsIk12cyI6MCwiRmx0IjowLCJJbXAiOjJ9; '
              'MUIDB=29136B8A85066B00244864BB84D46AA3')
    resp = session.get(f'https://www.bing.com/search?q={key}', headers={'Cookie': cookie})
    search_result = resp.html.xpath('//li[@class="b_algo"][1]//h2//text()')
    if search_result:
        nodes = [i.encode('latin1').decode('utf-8') for i in search_result]
        result = (True, ''.join(nodes))
    else:
        nodes = resp.html.xpath('//li[@class="b_no"][1]//h1//text()')
        result = (False, ''.join(nodes))
    status, title = result
    fmt = 'Result: {:4} Request: {}\n    {}'
    print(fmt.format(('FAIL', 'OK')[status], key, title))
[guest@localhost bingsearch]$ ./bingsearch.py 
Result: OK Request: как сделать бумажный самолетик
Как сделать далеко летающий самолет из бумаги. Оригами ...
Result: OK Request: как сделать бумажный кораблик
Кораблик из бумаги: 10 вариантов, 120 фото как сделать ...
Result: OK Request: как сделать бумажного журавля
Как сложить бумажного журавлика (с иллюстрациями)
[guest@localhost bingsearch]$
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB