BeautifulSoup 和 lxml 找不到 div 元素
BeautifulSoup and lxml cannot find div element
刚开始在 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,它 returns 我 none:
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 "into" 处,完整的源代码大约 500kb.If 我尝试寻找其他 div 附近,也没有运气。而如果我在源代码开头附近寻找一些 div,它会发现 it.And 更有趣的是,如果我尝试在源代码中寻找相同的 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 一样,它能够在使用 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 在 page.content 中查找 div 时,无论我直接分析响应还是将其保存到文件中,都不会再发生 luck.It然后分析文件。
我认为就是这样...我还尝试对 Mechanize 和 Requests 响应进行编码,正如我看到的那样,我是用 Selenium 完成的,但没有改变。我也尝试使用其他 BS 版本 (3.x),没有变化。
总结一下:
- 如果我在通过 Selenium 获得的源代码中查找带有 BS 或 lxml 的 div,它会找到 it.With 其他的,没有。
- 如果我在源代码的开头寻找其他 divs,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
谢谢。
您要查找的 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>
刚开始在 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,它 returns 我 none:
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 "into" 处,完整的源代码大约 500kb.If 我尝试寻找其他 div 附近,也没有运气。而如果我在源代码开头附近寻找一些 div,它会发现 it.And 更有趣的是,如果我尝试在源代码中寻找相同的 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 一样,它能够在使用 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 在 page.content 中查找 div 时,无论我直接分析响应还是将其保存到文件中,都不会再发生 luck.It然后分析文件。
我认为就是这样...我还尝试对 Mechanize 和 Requests 响应进行编码,正如我看到的那样,我是用 Selenium 完成的,但没有改变。我也尝试使用其他 BS 版本 (3.x),没有变化。
总结一下: - 如果我在通过 Selenium 获得的源代码中查找带有 BS 或 lxml 的 div,它会找到 it.With 其他的,没有。 - 如果我在源代码的开头寻找其他 divs,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
谢谢。
您要查找的 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>