【问题标题】:python requests & beautifulsoup bot detectionpython请求和beautifulsoup bot检测
【发布时间】:2019-02-03 17:45:00
【问题描述】:

我正在尝试使用 requests & beautifulsoup 抓取页面的所有 HTML 元素。我正在使用 ASIN(亚马逊标准识别号)来获取页面的产品详细信息。我的代码如下:

from urllib.request import urlopen
import requests
from bs4 import BeautifulSoup

url = "http://www.amazon.com/dp/" + 'B004CNH98C'
response = urlopen(url)
soup = BeautifulSoup(response, "html.parser")
print(soup)

但是output 没有显示页面的整个 HTML,所以我无法进一步处理产品详细信息。 对此有什么帮助吗?

编辑 1:

根据给定的答案,它显示了机器人检测页面的标记。我研究了一下,发现了两种破坏它的方法:

  1. 我可能需要在请求中添加标头,但我不明白标头的值应该是什么。
  2. 使用硒。 现在我的问题是,这两种方式都提供同等支持吗?

【问题讨论】:

  • 如果您能提供 B004CNH98C 应该是什么,这样人们就可以查看实际页面,那就太好了。我的猜测是一些 html 的东西隐藏在 javascript 函数下。您应该将页面加载到 Selenium 并单击它。
  • 同时我刚刚熟悉了 selenium webdriver。每次我尝试抓取每个页面时都会打开一个新的 chrome 窗口吗?
  • 使用无头选项。
  • 使用 javascript 框架的页面不能被 BS 抓取。既然亚马逊有这么好的 API,为什么还要刮?
  • 我认为我的国家不支持 Amazon API

标签: python html web-scraping beautifulsoup python-requests


【解决方案1】:

这里最好使用 fake_useragent 来让事情变得简单。随机用户代理通过真实世界的浏览器使用统计数据发送请求。如果您不需要动态内容,最好只通过 HTTP 请求页面内容并以编程方式对其进行解析。

import requests
from fake_useragent import UserAgent
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
ua=UserAgent()
hdr = {'User-Agent': ua.random,
      'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
      'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
      'Accept-Encoding': 'none',
      'Accept-Language': 'en-US,en;q=0.8',
      'Connection': 'keep-alive'}
url = "http://www.amazon.com/dp/" + 'B004CNH98C'
response = requests.get(url, headers=hdr)
print response.content

Selenium 用于浏览器自动化和动态内容的高级网页抓取。

【讨论】:

  • TypeError: get() got an unexpected keyword argument 'headers'
【解决方案2】:

正如一些 cmets 已经建议的那样,如果您需要在页面上以某种方式与 Javascript 交互,最好使用 selenium。但是,关于您使用标头的第一种方法:

import requests
from bs4 import BeautifulSoup

url = "http://www.amazon.com/dp/" + 'B004CNH98C'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}

response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text,"html.parser")

这些标题有点旧,但应该仍然可以使用。通过使用它们,您假装您的请求来自普通的网络浏览器。如果您使用 requests 没有这样的标头,您的代码基本上是在告诉服务器请求来自 python,大多数服务器都会立即拒绝。

fake-useragent 也可以是您的另一种选择,也许您也可以尝试一下。

【讨论】:

  • 如果“用户代理”采用任何预定义的格式来提供我的机器信息,我会感到困惑。我遇到了这个developers.whatismybrowser.com/useragents/explore/…。我想这将是我通过的标题,对吗?
  • 同样来自文档,它说定制的标题的优先级较低。这是否意味着在接受请求方面“优先级较低”?
  • 从您发布的浏览器列表中,您可以选择要使用的标题。然后,您的请求会假装来自此浏览器。我还没有找到关于“较少优先级”的文章,所以我只能假设是什么意思,但总的来说,服务器大多拒绝看起来以某种方式自动化的请求,以保持良好的性能。这就是为什么需要伪装成真正的浏览器以便服务器接受您的请求的原因。
  • 然而,现在大多数网站都为想要使用自动请求的人提供 API。这实际上对双方都有好处。 API 请求对服务器性能更好,对你来说也需要更少的代码,而且更直接。所以一般来说,我可以建议在尝试以“hacky”方式解析它之前检查页面是否提供 API。
【解决方案3】:

试试这个:

import requests
from bs4 import BeautifulSoup

url = "http://www.amazon.com/dp/" + 'B004CNH98C'
r = requests.get(url)
r = r.text

##options #1
#  print r.text

soup = BeautifulSoup( r.encode("utf-8") , "html.parser")

### options 2
print(soup)

【讨论】:

  • 已经尝试过这种方式,会导致“确保你不是机器人”页面。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-20
  • 2021-09-15
  • 1970-01-01
  • 2014-05-22
  • 1970-01-01
  • 1970-01-01
  • 2016-02-21
相关资源
最近更新 更多