BeautifulSoup和lxml找不到div元素

时间:2017-09-21 15:40:11

标签: python web-scraping beautifulsoup lxml mechanize

刚开始在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()

一切都运行良好,但Selenium需要花费太多时间,所以我首先转向机械化,以获取页面源:

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")

问题出现了:如果我尝试通过它的id找到一个特定的div,它就会返回我:

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和#34;代码,完整的源代码大约是500kb。如果我试着寻找附近的其他div,也没有运气。然而,如果我在源代码的开头附近寻找一些div,它会找到它。如果我尝试在Selenium获得的源代码中尝试查找相同的div(使用BS),那么更有趣的是使用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一样,它能够在使用Selenium获得的源代码中找到div,但不能在Mechanize中找到。所以我认为它可能与Mechanize有关,并转而使用Requests:

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的page.content时,使用BS或lxml,再次没有运气。我是否直接分析响应或是否将其保存到文件中然后分析文件。

我认为这是关于它的......我也尝试编码机械化和请求响应,因为我看到我用Selenium完成了它,但没有改变。我也试过使用其他BS版本(3.x),没有变化。

总结一下:   - 如果我在通过Selenium获得的源代码中查找带有BS或lxml的div,它会找到它。与其他的一样,没有。   - 如果我在源代码的开头寻找其他div,BS和lxml找到它,独立于获取代码的方法。   - 在检查时,每个案例都有div。

使用的版本: -python:2.7.9 -BeautifulSoup:4.6.0 - 机械化:0.3.5 - 请求:2.18.4 - 硒:3.5.0 -lxml:4.0.0 -OS:linux debian

谢谢。

1 个答案:

答案 0 :(得分:0)

您要查找的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>