背景
- 最近在爬一个空气质量的网站,数据比较多,而且网站还是采用的js动态渲染的方式!好吧! 我只能选择使用selenium了,直接模拟浏览器登录的方式抓取数据。另外,因为我想要全部的数据,所以,我还得获得网站提供的所有的城市和对应的有空气质量数据的年月。这样才能不用自己去输入,直接搞到全部。而我又发现,这一部分的内容他不是动态渲染过来的,所以我还是用我喜欢的requests请求再加xpath进行解析吧!
- 因为数据量超级大,所以它就需要很长的时间(爬了5个小时才搞了十分之一)。啊!反正我也不着急,用学校的电脑跑,没事!但是,但是,但是,我哭了!学校突然断网了,而且是断了好一会的那种。因为请求长时间没有响应,所以直接抛出异常了!!!!因为我为了方便,先爬到城市,在代码里直接就循环了,如果重新跑代码的话,相当于5个小时的工作白干了!!!!
- 然后我怕了(万一爬了百分之九十九,然后GG了咋办!),所以我就想,如果在请求的时候,如果没网了,就让它等待,直到有网再继续执行下去,这样不就不会抛出异常。
关键代码
- 当时我想了一个看起来非常low的方法来实现它。就是,我用try except的方式进行处理,然后外面写一个死循环,如果没有异常直接break;如果有异常,我就continue,让它再去请求(当然等了几秒)。好吧,说的有点乱,上low代码。
while True:
try:
html_adr = requests.get(url_adr,headers=headers)
except Exception as e:
print(e)
print("网络异常,重试中。。。")
time.sleep(10)
continue
break
- 但是,当我给Chromedriver的对象添加异常处理的时候,我发现,没网也不会报错。。。很无语了。这怎么办呢。
- 我又想了一个更low的办法,就是: 我发现当我请求时,有网和没网使用Chromedriver的get()方法请求时的title是不一样的,所以,我就用这个特征又又又又写了一个死循环。
while True:
page = driver.get(url)
time.sleep(1)
if(driver.title == "www.aqistudy.cn"):
print("网络异常,重试中。。。")
time.sleep(10)
continue
break
完整代码
import requests
from selenium import webdriver
from lxml import etree
import time
import os
headers = {"User-Agent" : "Opera/9.80(WindowsNT6.1;U;en)Presto/2.8.131Version/11.11"}
url_adr = "https://www.aqistudy.cn/historydata/"
while True:
try:
html_adr = requests.get(url_adr,headers=headers)
except Exception as e:
print(e)
print("网络异常,重试中。。。")
time.sleep(10)
continue
break
html_adr = html_adr.content.decode("utf-8")
content_adr = etree.HTML(html_adr)
href_list_adr = content_adr.xpath("/html/body/div[3]/div/div[1]/div[2]/div[2]/ul/div/li/a")
city = ""
driver = webdriver.Chrome()
for href_adr in href_list_adr:
city = href_adr.text
year = ""
month = ""
url_time = "https://www.aqistudy.cn/historydata/monthdata.php?city=" + href_adr.text
while True:
try:
html_time = requests.get(url_time,headers=headers)
except Exception as e:
print(e)
print("网络异常,重试中。。。")
time.sleep(10)
continue
break
html_time = html_time.content.decode("utf-8")
content_time = etree.HTML(html_time)
href_list = content_time.xpath("/html/body/div[3]/div[1]/div[2]/div[2]/div[2]/ul/li/a/@href")
for href in href_list:
year = str(href)[-6:-2]
month = str(href)[-2:]
print('正在抓取'+ city + '市' + year + '年' + '空气质量每日历史数据:' )
print('由于抓取数据较多,请您耐心等待:')
url = 'https://www.aqistudy.cn/historydata/daydata.php?city={}&month={}{}'.format(city,year,month)
while True:
page = driver.get(url)
time.sleep(1)
if(driver.title == "www.aqistudy.cn"):
print("网络异常,重试中。。。")
time.sleep(10)
continue
break
tr_list = driver.find_elements_by_tag_name('tr')
print(len(tr_list))
with open(r'd:\data.txt','a',encoding='utf8') as f:
for i in range(1, len(tr_list)):
td_list =tr_list[i].find_elements_by_tag_name('td')
dae = td_list[0].text
AQI = td_list[1].text
ql = td_list[2].text
PM2 = td_list[3].text
PM10 = td_list[4].text
SO2 = td_list[5].text
CO = td_list[6].text
NO2 = td_list[7].text
O3 = td_list[8].text
f.write('{},{},{},{},{},{},{},{},{},{}\n'.format(city,dae,AQI,ql,PM2,PM10,SO2,CO,NO2,O3))
print('抓取完毕')
print('文件存储在D:\data.csv')