好吧,如果 Google 为这些数据提供 API,那就太好了!也就是说,您仍然可以从网站上抓取一些数据。以下是如何去做...
安装萤火虫
我更喜欢Firefox 的Firebug,但 Chrome 的开发人员工具也应该可以工作。
调查
首先,让我们访问有问题的url并使用 Firebug 尝试看看发生了什么。使用 F12 激活 Firebug 或转到 Tools->Firebug->Open Firebug。首先单击“网络”选项卡并重新加载页面。这显示了所有提出的请求,并将让您深入了解该站点的工作方式。通常 flash 插件从外部加载数据,而不是将其嵌入到实际插件中,如果您查看请求,您会看到标记为 的请求POST service
。如果您将鼠标悬停在它上面,firebug 会显示完整的 url,您会看到该页面向http://www.google.com/transparencyreport/traffic/service
. 您可以单击请求并查看发送的标头、发布数据、响应和用于执行请求的 cookie。
如果您查看响应,您会看到似乎是格式错误的 JSON。据我所知,这似乎包含标准化交通数据点的列表。您实际上可以从 firebug 中剪切和粘贴响应,但由于这是一个 python 问题,让我们更加努力。
将数据导入 Python
为了成功发出 post 请求,我们需要(几乎)完成浏览器所做的所有事情。我们可以稍微作弊,只复制请求标头并从 firebug 中发布数据,以欺骗真实的请求。
标题和帖子数据
使用三引号将多行字符串粘贴到 shell 中。复制请求标头并将其粘贴。
>>> headers = """ <paste headers> """
接下来将其转换为 httplib2 的字典。我将使用列表理解(它根据换行符拆分字符串,然后在第一个 : 上拆分行并去除尾随空格,这给了我一个dict
可以转换为字典的双元素列表的列表),但是你可以随心所欲地做到这一点。你也可以手动创建字典,我只是发现这个更快。
>>> headers = dict([[s.strip() for s in line.split(':', 1)]
for line in headers.strip().split('\n')])
并复制帖子数据。
>>> body = """ <paste post data> """
提出请求
,我将使用httplib2,但还有一些其他的 http 客户端和一些不错的工具用于抓取网络,例如mechanize和scrapy。我们将使用 API 的 url、我们复制的标头和我们从 firebug 复制的发布数据发出 POST 请求。该请求返回一个响应头和内容的元组。
>>> import httplib2
>>> h = httplib2.Http()
>>> url = 'http://www.google.com/transparencyreport/traffic/service'
>>> resp, content = h.request(url, 'POST', body=body, headers=headers)
按摩数据
原始格式真的很奇怪,只有最高位似乎包含数据点,所以我会放弃其余的。
>>> cleaned = content.split("'")[0][4:-1] + ']'
现在它是有效的 JSON,所以我们可以将它反序列化为原生 python 数据类型。
>>> import json
>>> data = json.loads(cleaned)
我感兴趣的所有点都是浮点数,所以我将根据它进行过滤。
>>> data = [x for x in data if type(x) == float]
处理/保存数据
现在我们有了我们的数据,检查它,做额外的处理,等等......
>>> data[:5]
<<<
[44.73874282836914,
45.4061279296875,
47.5350456237793,
44.56114196777344,
46.08817672729492]
...或者只是保存它。
>>> with open('data.json', 'w') as f:
...: f.write(json.dumps(data))
我们还可以使用matplotlib(或其他一些绘图/绘图库)中的pyplot将其绘制出来。
>>> import matplotlib.pyplot as plt
>>> plt.plot(data)
结论
如果您只对一些事情感兴趣,您可以调整图表以显示您想要的内容,然后使用正确请求使用的请求标头/发布数据到http://www.google.com/transparencyreport/traffic/service
. 您可能希望比我更仔细地检查实际响应,我只是丢弃了对我没有意义的部分。希望他们会为这些数据公开一个公共 API。