前言:在上一篇文章中,我们介绍了在http://PM2.5.in这个网站采集空气质量的数据,本篇文章是对其产生的一些问题的另一种解决方案,提供更加权威的数据采集。
技术框架:selenium、json、etree
这里的selenium是一种自动化测试的工具,它可以帮助我们模拟浏览器打开网页并获取网页数据,本文之所以选择这种方式进行,是因为以requests方式直接请求无法获取到正确的数据,这个网页的数据是动态加载,需要用户执行点击操作才会被请求
我们还是按照常规套路来分析下这个网站,打开F12,看下这个网站的数据请求
可以发现这个网站的数据的请求接口,但当我们直接用requests去请求这个接口,会发现无法获取正确的数据,原因是这个网站采用了MmEwMD这个值进行了反爬虫,这个是一个比较常见的反爬虫措施,他这个值是在发起请求时动态生成的,最简单的解决这个问题的办法就是采用selenium之类的模拟浏览器方法进行请求,这样的话,发出的请求也会自动带上这个参数
请求的代码如下图所示
driverPath = 'browser\\chromedriver.exe'
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
# options.add_argument(('--proxy-server=http://' + ip))
browser = webdriver.Chrome(options=options, executable_path=driverPath)
browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
browser.get(self.url)
html = browser.page_source
browser.quit()
# print(html)
reponse = etree.HTML(html)
data = reponse.xpath('//body/text()')[0]
json_data = json.loads(data)
我们通过调用谷歌浏览器直接请求对应的页面,获取到数据后,关闭浏览器,通过etree解析网页结果,通过观察发现,我们获取到的数据是json数组,因此我们使用json解析数据,然后将对应的数据存储到数据库
result_list = json_data['data']['hour']
print(result_list)
for result in result_list:
item = dict()
item['affect'] = result['AFFECTINFO']
item['action'] = result['SUGGEST']
if('AQIPRIMPOLLUTE' in result):
item['primary_pollutant'] = result['AQIPRIMPOLLUTE']
else:
item['primary_pollutant'] = '无'
item['AQI'] = result['AQI']
item['PM2.5/1h'] = result['PM25']
item['PM10/1h&#