python - BeautifulSoup 和 lxml 找不到 div 元素

标签 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太耗时,所以我首先转向 Mechanize ,获取页面源:

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“内”,完整的源代码大约 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)

当使用 BS 或 lxml 查看 div 的 page.content 时,同样没有运气。无论我直接分析响应还是将其保存到文件中然后分析文件,都会发生这种情况。

我认为仅此而已...我还尝试对 Mechanize 和 Requests 响应进行编码,正如我所看到的那样,我是使用 Selenium 完成的,但没有任何变化。我也尝试使用其他 BS 版本 (3.x),没有变化。

总结一下: - 如果我在通过 Selenium 获得的源代码中寻找带有 BS 或 lxml 的 div,它会找到它。对于其他的,没有。 - 如果我在源代码的开头查找其他 div,BS 和 lxml 会找到它,与用于获取代码的方法无关。 - 经检查,div 在所有情况下都存在。

使用的版本: - python :2.7.9 -BeautifulSoup:4.6.0 - Mechanize :0.3.5 -要求:2.18.4 - Selenium :3.5.0 -lxml:4.0.0 -操作系统:linux debian

谢谢。

最佳答案

您要查找的 div 隐藏在可能通过 Javascript 处理的 HTML 注释中。您仍然可以使用 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>

关于python - BeautifulSoup 和 lxml 找不到 div 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46348050/

相关文章:

python - 网络抓取最常见的名字

r - 从 <dl> 标签中抓取 HTML 文本

python - 用漂亮的汤解析数据表

python - 使用selenium webdriver爬取网页时,服务器如何区分是机器人还是人?

Python - argparse 需要或

python - 从其他模型的字段创建计算字段

python - 使用 postman 发出 `_doPostBack` 请求

python - Beautiful Soup 默认解码字符集?

python 正则表达式: extract special substring in a hyperlink

python - 如何根据相应系列列中的值对一系列列应用函数?