从 python 调用 url 时获取“错误”页面源

Posted

技术标签:

【中文标题】从 python 调用 url 时获取“错误”页面源【英文标题】:Getting ‘wrong’ page source when calling url from python 【发布时间】:2016-08-26 13:53:08 【问题描述】:

尝试从网站检索页面源时,我得到的文本与通过网络浏览器查看相同页面源时完全不同(且更短)的文本。

https://***.com/questions/24563601/python-getting-a-wrong-source-code-of-the-web-page-asp-net

这个家伙有一个相关的问题,但获得了主页源而不是请求的源 - 我得到了完全陌生的东西。

代码是:

from urllib import request

def get_page_source(n):
    url = 'https://www.whoscored.com/Matches/' + str(n) + '/live'
    response = request.urlopen(url)
    return str(response.read())

n = 1006233
text = get_page_source(n)

这是我在此示例中定位的页面: https://www.whoscored.com/Matches/1006233/live

有问题的 url 包含页面源中的丰富信息,但在运行上述代码时我最终只得到以下内容:

文本 =

b'<html style="height:100%"><head><META NAME="ROBOTS" CONTENT="NOINDEX,
NOFOLLOW"><meta name="format-detection" content="telephone=no"><meta 
name="viewport" content="initial-scale=1.0"><meta http-equiv="X-
UA-Compatible" content="IE=edge,chrome=1"></head><body style="margin:0px;
height:100%"><iframe src="/_Incapsula_Resource?CWUDNSAI=24&
xinfo=0-12919260-0 0NNY RT(1462118673272 111) q(0 -1 -1 -1) r(0 -1) 
B12(4,315,0) U2&incident_id=276000100045095595-100029307305590944&edet=12&
cinfo=04000000" frameborder=0   margin 
margin>Request unsuccessful. Incapsula incident ID: 
276000100045095595-100029307305590944</iframe></body></html>'

这里出了什么问题?即使没有发送重复请求,服务器也能检测到机器人吗?如果可以,如何检测?有没有办法解决?

【问题讨论】:

【参考方案1】:

您应该尝试在 HTTP 标头中设置“User-Agent”。

【讨论】:

【参考方案2】:

这里有几个问题。根本原因是您尝试抓取的网站知道您不是真人并且正在阻止您。许多网站只是通过检查标头来查看请求是否来自浏览器(机器人)来做到这一点。但是,该站点看起来像是使用 Incapsula,旨在提供更复杂的保护。您可以尝试以不同的方式设置您的请求,以通过设置标题来欺骗页面上的安全性 - 但我怀疑这会起作用。

import requests

def get_page_source(n):
    url = 'https://www.whoscored.com/Matches/' + str(n) + '/live'
    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)
    return response.text

n = 1006233
text = get_page_source(n)
print text

该网站似乎也使用了验证码 - 旨在防止网络抓取。如果一个网站正在努力防止抓取 - 这很可能是因为他们提供的数据是专有的。我建议寻找另一个提供此数据的网站 - 或尝试使用官方 API。

看看这个 (https://***.com/a/17769971/701449) 不久前的回答。看起来 whoscored.com 使用 OPTA API 来提供信息。您也许可以跳过中间人,直接进入数据源。祝你好运!

【讨论】:

【参考方案3】:

以下是解决此问题的一种方法。第一次运行脚本时,您可能需要在 webdriver 打开的窗口中输入验证码,但之后您应该可以继续使用了。然后,您可以使用 beautifulsoup 浏览响应。

from selenium import webdriver

def get_page_source(n):

    wd = webdriver.Chrome("/Users/karlanka/Downloads/Chromedriver")
    url = 'https://www.whoscored.com/Matches/' + str(n) + '/live'

    wd.get(url)

    html_page = wd.page_source
    wd.quit()

【讨论】:

以上是关于从 python 调用 url 时获取“错误”页面源的主要内容,如果未能解决你的问题,请参考以下文章

从 google play 服务 api 调用个人资料图片 url 时发生错误

如何从python中的URL获取标头的值? [复制]

Python请求数据错误?

Python:从 urllib2.urlopen 调用中获取 HTTP 标头?

如何修复 HTTP 错误获取 URL。爬行时Java中的状态= 500?

从 Python 运行时获取 bat 文件的错误级别