【问题标题】:Web scraping urlopen in python在python中抓取urlopen
【发布时间】:2011-11-01 18:26:48
【问题描述】:

我正在尝试从该网站获取数据: http://www.boursorama.com/includes/cours/last_transactions.phtml?symbole=1xEURUS

似乎 urlopen 没有获取 html 代码,我不明白为什么。 它是这样的:

html = urllib.request.urlopen("http://www.boursorama.com/includes/cours/last_transactions.phtml?symbole=1xEURUS")
print (html)

我的代码是对的,我得到了其他网页的html源代码一样的,但是好像不能识别这个地址。

它打印:b''

也许另一个图书馆更合适?为什么urlopen不返回网页的html代码? 帮忙谢谢!

【问题讨论】:

  • 在 SO 上的网络连接主题上搜索线程会为您提供大量信息。但这对于新用户来说并不是一个严重的错误,无论如何。所以我赞成你,而不是问题,欢迎你。

标签: python urlopen


【解决方案1】:

我已经用httplib2 和在终端上用 curl 测试过你的 URL。两者都工作正常:

URL = "http://www.boursorama.com/includes/cours/last_transactions.phtml?symbole=1xEURUS"
h = httplib2.Http()
resp, content = h.request(URL, "GET")
print(content)

所以对我来说,要么 urllib.request 中存在错误,要么发生了非常奇怪的客户端-服务器交互。

【讨论】:

  • 这是一个错字,我的真实代码包括“”以使其成为一个字符串。它不起作用。我的问题是一个真正的问题
  • @jazz 可能是发送压缩数据的服务器,urllib 有点受限。
  • @Robert:很遗憾没有;响应是空的,在 Python 2 中它也可以正常工作。它必须特定于 Python 3 和 urllib.request。
  • @jazz 但Content-lengthresponse = urllib.request.urlopen(url) 上是7787,这表明除了标头之外还发送了一些东西——用在线工具查看它会显示相同的内容长度,但实际来源代码,暗示它不是一个空响应。所以,是的,urllib.request 发生了一些奇怪的事情。
【解决方案2】:

就个人而言,我写道:

# Python 2.7

import urllib

url = 'http://www.boursorama.com/includes/cours/last_transactions.phtml?symbole=1xEURUS'
sock = urllib.urlopen(url)
content = sock.read() 
sock.close()

print content

Et si tu parles français,.. bonjour sur stackoverflow.com !

更新 1

事实上,我现在更喜欢使用下面的代码,因为它更快:

# Python 2.7

import httplib

conn = httplib.HTTPConnection(host='www.boursorama.com',timeout=30)

req = '/includes/cours/last_transactions.phtml?symbole=1xEURUS'

try:
    conn.request('GET',req)
except:
     print 'echec de connexion'

content = conn.getresponse().read()

print content

在此代码中将 httplib 更改为 http.client 应该足以使其适应 Python 3。

.

我确认,通过这两个代码,我获得了我看到您感兴趣的数据的源代码:

        <td class="L20" width="33%" align="center">11:57:44</td>

        <td class="L20" width="33%" align="center">1.4486</td>

        <td class="L20" width="33%" align="center">0</td>

</tr>

                                        <tr>

        <td  width="33%" align="center">11:57:43</td>

        <td  width="33%" align="center">1.4486</td>

        <td  width="33%" align="center">0</td>

</tr>

更新 2

在上面的代码中添加下面的sn-p可以让你提取我想你想要的数据:

for i,line in enumerate(content.splitlines(True)):
    print str(i)+' '+repr(line)

print '\n\n'


import re

regx = re.compile('\t\t\t\t\t\t<td class="(?:gras )?L20" width="33%" align="center">(\d\d:\d\d:\d\d)</td>\r\n'
                  '\t\t\t\t\t\t<td class="(?:gras )?L20" width="33%" align="center">([\d.]+)</td>\r\n'
                  '\t\t\t\t\t\t<td class="(?:gras )?L20" width="33%" align="center">(\d+)</td>\r\n')

print regx.findall(content)

结果(仅结束)

.......................................
.......................................
.......................................
.......................................
98 'window.config.graphics = {};\n'
99 'window.config.accordions = {};\n'
100 '\n'
101 "window.addEvent('domready', function(){\n"
102 '});\n'
103 '</script>\n'
104 '<script type="text/javascript">\n'
105 '\t\t\t\tsas_tmstp = Math.round(Math.random()*10000000000);\n'
106 '\t\t\t\tsas_pageid = "177/(includes/cours/last_transactions)"; // Page : boursorama.com/smartad_test\n'
107 '\t\t\t\tvar sas_formatids = "8968";\n'
108 '\t\t\t\tsas_target = "symb=1xEURUS#"; // TargetingArray\n'
109 '\t\t\t\tdocument.write("<scr"+"ipt src=\\"http://ads.boursorama.com/call2/pubjall/" + sas_pageid + "/" + sas_formatids + "/" + sas_tmstp + "/" + escape(sas_target) + "?\\"></scr"+"ipt>");\t\t\t\t\n'
110 '\t\t\t</script><div id="_smart1"><script language="javascript">sas_script(1,8968);</script></div><script type="text/javascript">\r\n'
111 "\twindow.addEvent('domready', function(){\r\n"
112 'sas_move(1,8968);\t});\r\n'
113 '</script>\n'
114 '<script type="text/javascript">\n'
115 'var _gaq = _gaq || [];\n'
116 "_gaq.push(['_setAccount', 'UA-1623710-1']);\n"
117 "_gaq.push(['_setDomainName', 'www.boursorama.com']);\n"
118 "_gaq.push(['_setCustomVar', 1, 'segment', 'WEB-VISITOR']);\n"
119 "_gaq.push(['_setCustomVar', 4, 'version', '18']);\n"
120 "_gaq.push(['_trackPageLoadTime']);\n"
121 "_gaq.push(['_trackPageview']);\n"
122 '(function() {\n'
123 "var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\n"
124 "ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n"
125 "var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n"
126 '})();\n'
127 '</script>\n'
128 '</body>\n'
129 '</html>'



[('12:25:36', '1.4478', '0'), ('12:25:33', '1.4478', '0'), ('12:25:31', '1.4478', '0'), ('12:25:30', '1.4478', '0'), ('12:25:30', '1.4478', '0'), ('12:25:29', '1.4478', '0')]

我希望您不打算在外汇上“玩”交易:这是快速赚钱的最佳方式之一。

更新 3

对不起!我忘了你是使用 Python 3。所以我认为你必须像这样定义正则表达式:

regx = re.compile(b'\t\t\t\t\t......)

也就是说在字符串前加上b,否则你会得到类似this question的错误

【讨论】:

  • 谢谢,今晚我才能测试代码。你确定你得到了它的html源代码吗?是的,我在 python 3 ;-)
  • @Kingpin 是的,我明白了,我很少发布我没有测试过的代码。但我使用的是 Python 2.7。然后我了解到您使用的是 Python 3,看到 print(html) 带有括号,但我没有尝试 Python 3 足以知道我的代码在 Python 3 中会失败。抱歉
  • @Robert S. 我们知道,我们知道。当有人使用正则表达式从 HTML 源代码中提取数据时,总是有同样的反应很累。 sn-p 有效,我在 2 分钟内就写好了。您准备好帮助 Kingpin 在 1 或 2 小时内学习 BeautifulSoup 了吗?顺便说一句,BS 比纯正则表达式应用程序慢 10 倍。
  • @euquem 很公平——我只是认为应该告诉他这并不总是一个好主意。使用库意味着您不必手动编写正则表达式,这反过来又使您的代码更加健壮(并且更具可读性),并且您不必在每次糟糕的 HTML 破坏您的正则表达式时修复错误。但我明白你的意思;有时你可以使用正则表达式。
  • @Robert S. 我同意:并不总是一个好方法。但最好让对方知道原因和时间。它本质上是解析正则表达式无法实现的 stricto sensu ;但是在这里,他不想解析,他只想分析并找到源代码的特定且有限的部分。 - 关于经常修复错误,当总是分析源代码的同一部分时,情况并非如此,这就是我所相信的,也许我错了? - 顺便说一句,我特别喜欢正则表达式,所以制作正则表达式的模式对我来说不是问题。
【解决方案3】:

我怀疑正在发生的事情是服务器正在发送压缩数据而没有告诉您它正在这样做。 Python 的标准 HTTP 库无法处理压缩格式。
我建议获取 httplib2,它可以处理压缩格式(通常比 urllib 好得多)。

import httplib2
folder = httplib2.Http('.cache')
response, content = folder.request("http://www.boursorama.com/includes/cours/last_transactions.phtml?symbole=1xEURUS")

print(response) 显示来自服务器的响应:
{'status': '200', 'content-length': '7787', 'x-sid': '26,E', 'content-language': 'fr', 'set-cookie': 'PHPSESSIONID= ed45f761542752317963ab4762ec604f;路径=/; domain=.www.boursorama.com', 'expires': 'Thu, 19 Nov 1981 08:52:00 GMT', 'vary': 'Accept-Encoding,User-Agent', 'server': 'nginx', 'connection': 'keep-alive', '-content-encoding': 'gzip', 'pragma': 'no-cache', 'cache-control': 'no-store, no -cache, must-revalidate, post-check=0, pre-check=0', 'date': 'Tue, 23 Aug 2011 10:26:46 GMT', 'content-type': 'text/html; charset=ISO-8859-1', '内容位置': 'http://www.boursorama.com/includes/cours/last_transactions.phtml?symbole=1xEURUS'}

虽然这并不能证实它已被压缩(毕竟我们现在告诉服务器我们可以处理压缩),但它确实为理论提供了一些支持。

您猜对了,实际内容存在于content。简单地看一下它就会告诉我们它正在工作(我只是要粘贴一点点):
b'&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"\n\t"http://

编辑:是的,这确实创建了一个名为 .cache 的文件夹;我发现当涉及到 httplib2 时,使用文件夹总是更好,之后您可以随时删除该文件夹。

【讨论】:

    猜你喜欢
    • 2018-09-29
    • 1970-01-01
    • 2020-07-07
    • 2011-07-12
    • 2023-03-11
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 2020-10-29
    相关资源
    最近更新 更多