Python3爬虫小程序——爬取各类天气信息(2)

【静态页面信息的爬取】

更新:有关代码已上传到我的GitHub上,点击打开链接

根据前面做的那个爬虫,进行了一些修改,例如对headers信息的伪装。通过利用Fiddler抓包软件,抓到headers信息,然后构造我们的头信息进行爬虫设计。抓包抓到的数据如下图所示:

Client中就是我们需要构造的信息,部分构造代码如下所示:

 

#模拟成浏览器
headers={"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
         "Accept-Encoding":"gbk,utf-8,gb2312",
         "Accept-Language":"zh-CN,zh;q=0.8",
         "User-Agent":"Mozilla/5.0(Windows NT 10.0; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
         "Connection":"keep-alive"}
opener=urllib.request.build_opener()
headall=[]
for key,value in headers.items():
    item=(key,value)
    headall.append(item)
opener.addheaders=headall


所有代码如下所示:

 

 

#coding=utf-8
#北京及周边省会城市污染数据、天气数据每小时监测值爬虫程序
import urllib.request
import re
import urllib.error
import time
import traceback
#模拟成浏览器
headers={"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
         "Accept-Encoding":"gbk,utf-8,gb2312",
         "Accept-Language":"zh-CN,zh;q=0.8",
         "User-Agent":"Mozilla/5.0(Windows NT 10.0; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
         "Connection":"keep-alive"}
opener=urllib.request.build_opener()
headall=[]
for key,value in headers.items():
    item=(key,value)
    headall.append(item)
opener.addheaders=headall
#将opener安装为全局
urllib.request.install_opener(opener)
def get_pm25_and_weather(city):
    #首先执行获取空气质量数据,返回数据更新时间
    data_time=getpm25(city)
    #然后将获取到的数据更新时间赋值给获取天气数据函数使用
    getweather(city,data_time)
def getpm25(city):
    try:
        #设置url地址
        url="http://pm25.in/"+city
        data=urllib.request.urlopen(url).read().decode("utf-8")
        print("城市:"+city)
        #构建数据更新时间的表达式
        data_time='<div class="live_data_time">\s{1,}<p>数据更新时间:(.*?)</p>'
        #寻找出数据更新时间
        datatime=re.compile(data_time,re.S).findall(data)
        print("数据更新时间:"+datatime[0])
        #构建数据收集的表达式
        data_pm25='<div class="span1">\s{1,}<div class="value">\n\s{1,}(.*?)\s{1,}</div>'
        data_o3='<div class="span1">\s{1,}<div class ="value">\n\s{1,}(.*?)\s{1,}</div>'
        #寻找出所有的监测值
        pm25list=re.compile(data_pm25,re.S).findall(data)
        o3list=re.compile(data_o3,re.S).findall(data)
        #将臭氧每小时的值插入到原列表中
        pm25list.append(o3list[0])
        print("AQI指数,PM2.5,PM10,CO,NO2,SO2,O3:(单位:μg/m3,CO为mg/m3)")
        print(pm25list)
        #将获取到的值写入文件中
        writefiles_pm25(city,datatime,pm25list)
        #返回数据更新时间值
        return datatime
    except urllib.error.URLError as e:
        print("获取空气质量数据函数出现URLERROR!一分钟后重试……")
        get_exception("获取空气质量数据异常", e)
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)
        time.sleep(60)
        #出现异常则过一段时间重新执行此部分
        getpm25(city)
    except Exception as e:
        print("获取空气质量数据函数出现EXCEPTION!十秒钟后重试……")
        print("Exception:"+str(e))
        get_exception("获取空气质量数据异常",e)
        time.sleep(10)
        # 出现异常则过一段时间重新执行此部分
        getpm25(city)
def writefiles_pm25(filename,datatime,pm25list):
    try:
        #将获取的数据写入文件中,数据分别为时间,AQI指数,PM2.5,PM10,CO,NO2,SO2,O3。(单位:μg/m3,CO为mg/m3)
        with open("D:\mydata\data_pm25\data_pm25_"+filename+".txt","a",errors="ignore") as f:
            f.write(str(datatime[0]))
            f.write(",")
            for pm25 in pm25list:
                f.write(str(pm25))
                f.write(",")
            f.write("\n")
        print("该条空气质量数据已添加到文件中!")
    except Exception as e:
        print("空气质量数据写入文件函数出现异常!将跳过此部分……")
        print("Exception:"+str(e))
        traceback.print_exc()  #获得错误行数
        get_exception("空气质量数据写入文件异常",e)
        pass
def getweather(city,datatime):
    try:
        #构建url
        url="http://"+city+".tianqi.com/"
        data=urllib.request.urlopen(url).read().decode("gbk")
        #构建数据收集的表达式
        data_weather='<li class="cDRed">(.*?)</li>'
        data_wind='<li style="height:18px;overflow:hidden">(.*?)</li>'
        data_temperature='<div id="rettemp"><strong>(.*?)°'
        data_humidity='</strong><span>相对湿度:(.*?)</span>'
        #寻找出所有的监测值
        weatherlist=re.compile(data_weather,re.S).findall(data)
        windlist=re.compile(data_wind,re.S).findall(data)
        temperaturelist=re.compile(data_temperature,re.S).findall(data)
        humiditylist=re.compile(data_humidity,re.S).findall(data)
        #将其他值插入到天气列表中
        weatherlist.append(windlist[0])
        weatherlist.append(temperaturelist[0])
        weatherlist.append(humiditylist[0])
        print("天气状况,风向风速,实时温度,相对湿度:")
        print(weatherlist)
        #将获取到的值写入文件中
        writefiles_weather(city,datatime,weatherlist)
    except urllib.error.URLError as e:
        print("获取天气状况数据出现URLERROR!一分钟后重试……")
        get_exception("获取天气状况数据异常",e)
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)
        time.sleep(60)
        #出现异常则过一段时间重新执行此部分
        getweather(city,datatime)
    except Exception as e:
        print("获取天气状况数据出现EXCEPTION!十秒钟后重试……")
        print("Exception:"+str(e))
        get_exception("获取天气状况数据异常",e)
        time.sleep(10)
        # 出现异常则过一段时间重新执行此部分
        getweather(city,datatime)
def writefiles_weather(filename,datatime,weatherlist):
    try:
        #将获取的数据写入文件中,数据分别为时间,天气状况,风向风速,实时温度,相对湿度。
        with open("D:\mydata\data_weather\data_weather_"+filename+".txt","a",errors="ignore") as f:
            f.write(str(datatime[0]))
            f.write(",")
            for weather in weatherlist:
                f.write(str(weather))
                f.write(",")
            f.write("\n")
        print("该条天气数据已添加到文件中!")
    except Exception as e:
        print("天气状况数据写入文件函数出现异常!将跳过此部分……")
        print("Exception:"+str(e))
        traceback.print_exc()  #获得错误行数
        get_exception("天气状况数据写入文件异常",e)
        pass
def get_exception(string,e):
    with open("D:\mydata\Error.txt","a",errors="ignore") as f:
        datetime=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        f.write(datetime+" 【"+string+"】"+str(e)+"\n")
    print("异常信息已经写入文档!")
#退出循环可用Ctrl+C键
while True:
    print("开始工作!")
    get_pm25_and_weather("beijing")
    get_pm25_and_weather("tianjin")
    get_pm25_and_weather("shijiazhuang")
    get_pm25_and_weather("taiyuan")
    get_pm25_and_weather("jinan")
    get_pm25_and_weather("shenyang")
    get_pm25_and_weather("huhehaote")
    get_pm25_and_weather("zhengzhou")
    #每一小时执行一次
    print("休息中……")
    print("\n")
    time.sleep(3600)


在上面的代码中,我们可以在后续的工作当中进行修改:

 

(1)对正则表达式进行简化。

(2)读取到的数据可以不写到文本文件中,而是直接写到数据库当中,方便后面的数据使用。

 

而且目前写文件存在这样一个问题:

这个问题只存在于天气情况写文件操作上,当天气情况得到以后,写文件却报错:

【天气状况数据写入文件异常】'NoneType' object is not subscriptable.

这个问题还不知道出现在哪里,不是总是出现,只是偶尔出现一次,感觉好奇怪+_+

 

后面我会看看对动态页面的爬取(使用到的工具是selenium+phantomJS),对博客进行更新。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值