我正在使用Python请求抓取Wikia页面。但是有一个问题:请求请求不会给我相同的HTML ,因为我的浏览器使用相同的页面。
为了进行比较,here's the page Firefox gets me和here's the page requests fetches(下载它们进行查看 - 抱歉,没有简单的方法可以直观地从其他网站托管一些HTML)。
您会注意到一些差异(super unfriendly diff)。有一些小东西,比如beinig以不同的顺序排序等等,但也有一些非常非常大的东西。最重要的是缺少最后六个<img>
以及整个导航和页脚部分。即使在原始HTML中,它看起来像页面突然切断。
为什么会发生这种情况,有没有办法解决这个问题?我已经想到了很多东西,其中没有一个是富有成效的:
User-Agent
和所有,1:1复制到请求请求中,但没有任何改变。如果您知道这种情况可能发生的方式以及解决问题的方法,那就太棒了。谢谢!
答案 0 :(得分:5)
我遇到了类似的问题:
要解决此问题,我最终更换了 urllib.request 的 requests 库。
基本上,我更换了:
import requests
session = requests.Session()
r = session.get(URL)
使用:
import urllib.request
r = urllib.request.urlopen(URL)
然后它奏效了。
也许其中一个图书馆在幕后做了一些奇怪的事情?不确定这是否是你的选择。
答案 1 :(得分:2)
我建议您不要向您的请求发送正确的标头(或发送错误的标头)。这就是你获得不同内容的原因。以下是带标头的HTTP请求示例:
url = 'https://www.google.co.il/search?q=eminem+twitter'
user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36'
# header variable
headers = { 'User-Agent' : user_agent }
# creating request
req = urllib2.Request(url, None, headers)
# getting html
html = urllib2.urlopen(req).read()
如果您确定要发送正确的标题,但仍然会得到不同的HTML。您可以尝试使用selenium。它允许您直接使用浏览器(如果您的机器没有GUI,则使用phantomjs)。使用selenium,您只需直接从浏览器中获取HTML。
答案 2 :(得分:0)
我看到的很多差异告诉我内容仍然存在,它只是以不同的顺序呈现,有时间距不同。
您可能会根据多种不同的内容收到不同的内容:
如果你可以在Diff的顶部包含所有标题,那么我们可以更好地理解它。
我怀疑应用程序选择不渲染某些图像,因为它们没有针对它认为的某种机器人/移动设备(Python请求)进行优化
仔细观察差异,似乎两个请求中都加载了所有,只是格式不同。
答案 3 :(得分:0)
我在申请页面时遇到了类似的问题。然后我注意到我使用的URL需要'http'作为URL的前缀,但我在前面加上'https'。我的请求网址看起来像https://example.com。因此,请将网址设为http://example.com。希望它能解决问题。
答案 4 :(得分:0)
也许请求和浏览器使用不同的方式来呈现来自WEB服务器的原始数据,而上例中的diff仅适用于呈现的html。
我发现,当html损坏时,不同的浏览器(例如Chrome和Safari,在解析时使用不同的方法进行修复。因此,也许与Requests和Firefox是同一个想法。
在Requests和Firefox中,我建议对原始数据进行比较,即套接字中的字节流。请求可以使用响应对象的.raw属性来获取套接字中的原始数据。 (http://docs.python-requests.org/en/master/user/quickstart/)如果双方的原始数据相同并且HTML中存在一些损坏的代码,则可能是由于解析损坏的html时Request和浏览器的自动修复策略不同所致。
答案 5 :(得分:0)
(也许我最近的经验会有所帮助)
我在Amazon上遇到了刮刮的相同问题:我的本地计算机能够处理所有页面,但是当我在Google Cloud实例上移动项目时,对于某些我刮刮的物品的行为发生了改变。
在我的本地计算机上,我正在使用请求库,如下所示:
page = requests.get(url_page, headers=self.headers)
page=page.content
根据我的本地浏览器在班级中指定的标头
headers = {
"User-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36 OPR/67.0.3575.137"}
但是在Google Cloud实例上使用此设置后,页面显示不完整
以下实现涉及没有标题的 urllib
req = urllib.request.Request(
url_page,
data=None
)
f = urllib.request.urlopen(req)
page = f.read().decode('utf-8')
self.page = page
此解决方案可在两台计算机上使用;在进行此尝试之前,我还尝试使用相同的标头,但问题并未解决,因此我假定存在问题(可能是因为我不正确地标识为另一个客户端)而删除了标头。
因此,我的代码可以正常工作,并且我仍然可以使用 beautifulsoup 处理页面的内容,就像在我的类中实现的以下方法一样,目的是从中提取文本页面的特定部分。
def find_data(self, div_id):
soup = BeautifulSoup(self.page, features = "lxml")
text = soup.select("#"+div_id)[0].get_text()
text = text.strip()
text = str(text)
text = text.replace('"', "")
return text