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),对博客进行更新。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
爬取空气质量检测网的部分城市的历年每天质量数据 思路----------------------------------------- 从某城市的空气质量网页获取某市每月的链接,再爬取每个月的表格数据。连云港市:https://www.aqistudy.cn/historydata/daydata.php?city=连云港 连云港2014年5月的空气质量:https://www.aqistudy.cn/historydata/daydata.php?city=连云港&month=2014-05 遇到的问题----------------------------------------- 获取的网页中的表格数据隐藏,尝试requests无法获取。判断可能是动态加载的网页 尝试----------------------------------------- 1. 通过XHR,js查找隐藏数据的加载网页,没有找到。 2. 使用phantomjs.get() result=pd.read_html ,可以获得隐藏的表格数据,但是并不稳定,只是偶尔出现加载的表格数据,无法大规模的获取 解决方法----------------------------------------- 查找资料得知这个网站的表格数据在Console里的items中, 使用selenium的webdriver.firefox(),driver.execute_script("return items") 数据可获得。 仍遇到的问题:----------------------------------------- 爬取一个网页可获得数据,但是连续的获取网页,会出现两个错误。 1.Message: ReferenceError: items is not defined 2.connection refused 解决方法: 1.connection refused问题,可能是网页开太多,使用driver.quit() 2. 如果 execute_script 还是出错,可尝试pd.read_html获取信息。之前用phantomjs获取的时候输出空的表格,可能由于加载不够,用 Waite直到table出现之后再获取网页 Element=wait.until(EC.element_to_be_clickable((By.XPATH,"/html/body/div[3]/div[1]/div[1]/table/tbody"))) 3.之后出现偶尔出现输出为空,使用循环,如果输出表格为空,再重新获取。 if len(result)>1: filename = str(month) + '.xls' result.to_excel('E:\python\案例程序\data\\' + filename) print('成功存入'+filename) driver.quit() else: driver.quit() return getdata(monthhref,month)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值