BeautifulSoup и lxml не могут найти элемент div
Только что начал веб-скрейпинг в python, и у меня возникли некоторые проблемы.
Я начал использовать Selenium для загрузки источника веб-страницы и сохранения его:
from selenium import webdriver
driver= webdriver.Firefox()
driver.get("https://www.website.com")
f=open('output.txt','w')
f.write(driver.page_source.encode('utf-8'))
f.close()
driver.quit()
Все работало отлично, но селен занимает слишком много времени, поэтому я сначала обратился к механизации, чтобы получить страницу источника:
import mechanize
browser = mechanize.Browser()
browser.set_handle_robots(False)
cookies = mechanize.CookieJar()
browser.set_cookiejar(cookies)
browser.addheaders = [('User-agent', 'Mozilla/5.0')]
browser.set_handle_refresh(False)
browser.open("https://www.website.com")
Здесь возникает проблема: если я пытаюсь найти конкретный div по его id, он не возвращает мне ничего:
from bs4 import BeautifulSoup as BS
soup= BS(browser.response().read(),'lxml')
print(soup.find(id="div_id"))
Хотя если я проверю исходный код, полученный с помощью mechanize с регулярным текстовый редактор я могу найти. Это что-то вроде:
<div id="div_id" data referrer="div_id">
Этот div имеет много других дочерних элементов, он расположен примерно на 1/5 "в" коде, а полный исходный код составляет около 500 Кб.Если я попытаюсь вместо этого искать других див поблизости, тоже не повезет. В то время как если я ищу какой-то div В начале исходного кода, он находит его.И что еще интереснее, если я попытаюсь найти тот же div (с BS), в исходном коде, полученном с Selenium, а не с Mechanize, он способен найти его, Хотя div кажется совершенно одинаковым при проверке с помощью текстового редактора.
Я попробовал использовать все Парсеры, поддерживаемые BS, но безуспешно. Поэтому я подумал, что это, возможно, имеет какое-то отношение к BS, и я попытался сделать то же самое с lxml:
from lxml import etree
parser= etree.HTMLParser()
tree= etree.parse(open('source.txt'),parser)
results= tree.xpath('//div[@id="div_id"]')
print(etree.tostring(results[0]))
Как и в случае с BS, он смог найти div в исходном коде, полученном с помощью Selenium, но не с Mechanize. Поэтому я подумал, что это может иметь какое-то отношение к механизации, и обратился к использованию запросов:
import requests
from fake_useragent import UserAgent
ua=UserAgent()
url= 'https://www.website.com'
headers= {'User-agent': str(ua.chrome)}
page = requests.get(url, headers=headers)
Когда смотрели в страницах.контент для div, либо с BS, либо с lxml, опять же нет luck.It происходит независимо от того, анализирую ли я непосредственно ответ или сохраняю его в файл, а затем анализирую файл.
И я думаю, что это все... Я также попробовал кодировать ответы Mechanize и Requests, как я видел, я сделал это с селеном, но никаких изменений. Я также попытался использовать другую версию BS (3.x), без изменений.
Подведем итоги: - Если я ищу div с BS или lxml в исходном коде, полученном через Селен, он находит его.С другими-нет. - Если я ищу другие divs в начале исходного кода, BS и lxml находят его, независимо от метода, используемого для получения кода. - При осмотре, див есть в каждом случае.
Используемые версии: -питон: 2.7.9 - BeautifulSoup: 4.6.0 - Механизация: 0.3.5 - Запросы: 2.18.4 - Селен: 3.5.0 - lxml: 4.0.0 - OS: linux debian
Спасибо.
1 ответ:
Div, который вы ищете, скрыт внутри HTML-комментария, который, вероятно, обрабатывается с помощью Javascript. Вы все еще можете использовать
requests
для первого извлечения скрытого HTML следующим образом:from bs4 import BeautifulSoup, Comment import requests id = "pagelet_forsale_island" r = requests.get("https://www.facebook.com/groups/1584160618524185/") soup = BeautifulSoup(r.content, "html.parser") for comment in soup.find_all(string=lambda text:isinstance(text, Comment)): if id in comment: hidden_soup = BeautifulSoup(comment, "html.parser") for div in hidden_soup.find_all('div', id=id): print div
Это позволяет BeautifulSoup найти все комментарии в HTML, а затем определить, содержат ли они Ваш
id
. Если совпадение найдено, сам комментарий снова передается BeautifulSoup для дальнейшей обработки. Это будет отображать ваш<div>
Как:<div data-referrer="pagelet_forsale_island" id="pagelet_forsale_island"></div>