selenium + requests + xpath实现空气质量数据的爬取并实现网络异常等待

背景

  • 最近在爬一个空气质量的网站,数据比较多,而且网站还是采用的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"}
#headers = {"User-Agent" : "Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0"}

# 获取地区
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
    # print(url_time)

    
    # 添加了异常处理
    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")
    # print(html_time)
    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") # 获取时间
    # print(str(href_list))
    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')
        # break
    # break


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值