python 中的 Web Scraping:BS、selenium 和 None 错误

Posted

技术标签:

【中文标题】python 中的 Web Scraping:BS、selenium 和 None 错误【英文标题】:Webscraping in python: BS, selenium, and None error 【发布时间】:2016-06-17 01:17:16 【问题描述】:

我想使用 python webscraping 来为我所做的一个机器学习应用程序提供数据,该应用程序会做一个摘要摘要,以简化我的日常研究工作。 我似乎遇到了一些困难,因为我在网上使用了很多建议,比如这个:Python Selenium accessing html source 我不断收到 AttributeError: 'NoneType' 对象没有属性 'page_source'/'content' 取决于尝试/使用的模块 我需要这个资源来喂漂亮的汤来抓取资源并找到我的 ml 脚本。 我的第一次尝试是使用请求:

from bs4 import BeautifulSoup as BS
import requests
import time
import datetime
print ('start!')
print(datetime.datetime.now())

page="http://www.genecards.org/cgi-bin/carddisp.pl?gene=COL1A1&keywords=COL1A1"

这是我的目标页面。我通常每天需要 20 个请求,所以我不想吸食网站,因为我同时需要它们,所以我想自动化检索任务,因为最长的部分是获取 url,加载它,复制并粘贴摘要。 我也很合理,因为在加载另一页之前我尊重一些延迟。 我尝试作为常规浏览器传递,因为该网站不喜欢机器人 (它不允许 /ProductRedirect 和一个我在谷歌找不到的数字?)

headers = 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0'
current_page = requests.get(page,  headers=headers)
print(current_page)
print(current_page.content)
soup=BS(current_page.content,"lxml")

我总是没有内容,而请求获取代码 200,我可以自己在 Firefox 中加载此页面。 所以我尝试了硒

from bs4 import BeautifulSoup as BS
from selenium import webdriver
import time
import datetime
print ('start!')
print(datetime.datetime.now())

browser = webdriver.Firefox()
current_page =browser.get(page)
time.sleep(10)

这可以工作并加载一个页面。我添加了延迟以确保不会向主机发送垃圾邮件并确保完全加载页面。 然后两者都没有:

html=current_page.content

也没有

html=current_page.page_source

也没有

html=current_page

用作以下的输入:

soup=BS(html,"lxml")

它总是说它没有 page_source 属性(虽然它应该有,因为它在 selenium 调用的网络浏览器窗口中正确加载)。

我不知道接下来该尝试什么。就好像user-agent header对请求不起作用,selenium返回的页面没有源很奇怪。

接下来我可以尝试什么?谢谢。

请注意,我也尝试过:

browser.get(page)
time.sleep(8)
print(browser)
print(browser.page_source)
html=browser.page_source
soup=BS(html,"lxml")
for summary in soup.find('section', attrs='id':'_summaries')
    print(summary)

但是虽然它可以获取源代码,但它只是在 BS 阶段失败了 ; "AttributeError: 'NoneType' 对象没有属性 'find'"

【问题讨论】:

你试过普通的 html 解析器吗? soup = BS(html, "html.parser") 我刚做了。我使用 lxml 是因为他们推荐它。无论如何html.parser仍然得到NoneType'对象没有属性'find'”。我正在尝试上一个能够打印源的解决方案的新东西,但我不明白为什么BS仍然不想解析它,一旦机器人的事情似乎过去了…… 【参考方案1】:

问题是您试图迭代.find() 的结果。相反,您需要.find_all():

for summary in soup.find_all('section', attrs='id':'_summaries')
    print(summary)

或者,如果只有一个元素,不要使用循环:

summary = soup.find('section', attrs='id':'_summaries')
print(summary)

【讨论】:

好吧,确实看起来更好。谢谢。这不是最初的问题,但除了语法错误之外,我尝试迭代 find_all 可迭代,因为我需要获取某个部分这个“_summaries”id,然后再次刮掉它的部分(在

标签之间正在填写文件并且到处都是)。你对此有什么建议吗?嵌套的 BS 对象是一种好习惯还是我可以在一个命令中实现它?

@AndoJurai 当然,循环内的 summary 变量是一个 BS Tag 实例 - 您可以像使用常规汤对象一样在其中搜索:例如 [p.get_text() for p in summary.find_all("p")]。希望对您有所帮助。 谢谢。实际上,soup.find_all("p") 有效(同时得到了一些我不想要的文本),但 summary.find_all("p") 和 soup.summary.find_all("p") 都没有。因为我感兴趣的部分是
;我还尝试了 _summaries、summaries、Summaries 作为标识符,但所有这些都带有此属性错误。使用 for a in soup.find_all(re.compile("Summ")) 得到什么,而 for a in soup.find_all(re.compile("section")) 得到太多东西。我无法真正了解 BS 的工作原理......【参考方案2】:

您不必将 html 转换为字符串对象。

试试:

html = browser.page_source
soup = BS(html,"lxml")

【讨论】:

是的,实际上这是可行的,str 是我的尝试之一。我仍然不明白为什么你不能将 browser.get(page) 分配给一个对象,然后问它 page_source,对我来说这很令人费解。我真的不熟悉这种对象管理;它与使用构造函数等不同。

以上是关于python 中的 Web Scraping:BS、selenium 和 None 错误的主要内容,如果未能解决你的问题,请参考以下文章

Python中的Web Scraping

web scraping python行中的多个属性(div和id)

从抓取bs4中过滤python中的数据

阅读OReilly.Web.Scraping.with.Python.2015.6笔记---Crawl

Python的基本Web Scraping(Beautifulsoup和Requests)

阅读OReilly.Web.Scraping.with.Python.2015.6笔记---找出网页中所有的href