当前位置:嗨网首页>书籍在线阅读

04-边界情况

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

[toc]

5.2.1 边界情况

前面的AJAX搜索脚本非常简单,不过我们还可以利用一些可能的边界情况使其进一步简化。目前,我们是针对每个字母执行查询操作的,也就是说我们需要执行26次单独的查询,并且这些查询结果又有很多重复。理想情况下,我们可以使用一次搜索查询就能匹配所有结果。接下来,我们将尝试使用不同字符来测试这种想法是否可行。如果将搜索条件置为空,其结果如下。

>>> url =
'http://example.python-scraping.com/ajax/search.json?page=0&page_ size=10&search_term='
>>> requests.get(url).json()['num_pages']
0

很不幸,这种方法并没有奏效,我们没有得到返回结果。下面我们再来尝试'*'是否能够匹配所有结果。

>>> requests.get(url + '*').json()['num_pages']
0

依然没有奏效。接下来我们再尝试一下'.',这是正则表达式里用于匹配所有字符的元字符。

>>> requests.get(url + '.').json()['num_pages']
26

太好了!服务端肯定是通过正则表达式进行匹配的。因此,我们现在可以把依次搜索每个字符替换成只对点号搜索一次了。

此外,我们还可以在AJAX的URL中使用 page_size 这个查询字符串的值设置页面大小。网站搜索界面中包含4、10、20这几种选项,其中默认值为10。因此,提高每个页面的显示数量到最大值,可以使下载次数减半。

>>> url =
'http://example.python-scraping.com/ajax/search.json?page=0&page_ size=20&search_term=.'
>>> requests.get(url).json()['num_pages']
13

那么,要是使用比网页界面选择框支持的每页国家(或地区)数更高的数值又会怎样呢?

>>> url =
'http://example.python-scraping.com/ajax/search.json?page=0&page_ size=1000&search_term=.'
>>> requests.get(url).json()['num_pages']
1

显然,服务端并没有检查该参数是否与界面允许的选项值相匹配,而是直接在一个页面中返回了所有结果。许多Web应用不会在AJAX后端检查这一参数,因为它们认为所有API请求只会来自Web界面。

现在,我们手工修改了这个URL,使其能够在一次请求中下载得到所有国家(或地区)的数据。下面是更新后进一步简化的实现,在该实现中数据将被保存到CSV文件当中。

from csv import DictWriter
import requests
PAGE_SIZE = 1000
template_url = 'http://example.python-scraping.com/ajax/' +
 'search.json?page=0&page_size={}&search_term=.'
resp = requests.get(template_url.format(PAGE_SIZE))
data = resp.json()
records = data.get('records')
with open('../data/countries_or_districts.csv', 'w') as countries_or_districts_ file:
    wrtr = DictWriter(countries_or_districts_file, fieldnames=records[0].keys())
    wrtr.writeheader()
    wrtr.writerows(records)