北京市2020年1月份历史天气爬取
视频教程(讲的阔以的)
1 确定目标网址
1.1 目标网址
[2345天气]
1.2 目标数据
北京2020年一月份
2 分析网页
分析过程大家去看视频吧,讲的很好,现学现卖
3 爬取js文件 爬取过程
1.构造URL
2.用requests获取js,处理成json样式,接下转换成标准的json
3.用demjson转换成标准的json
4.解析数据放入列表
5.封装成一个函数
这里使用的工具包分别有:requests、demjson、re
经过上面的分析,我们发现目标文件的地址的变化规律,是更改 日期和 地区编码
构造URL
所以根据变化规律构造URL地址,这里也可不用构造,因为我只爬取1个月份的,构造是为了以后方便
url :
#导入包
import requests
import re
import demjson
#定义日期和地区编码
date_nu = '202001'
org_code = '54511'
url_js = 'http://tianqi.2345.com/t/wea_history/js/{date}/{org}_{date}.js'.format(date=date_nu,org=org_code)
用requests获取文件
#构造headers
header_info = {'User-Agent':'Mozilla/5.0 (compatible; WOW64; MSIE 10.0; Windows NT 6.2)'}
#获取数据
resp = requests.get(url_js,headers = header_info)
# get 方法获取到的是一个对象,获取其中的文本使用resp.text
# 因为我们在后台看到,这里获取到的并不是以标准的json格式,这里把前后不需要的截取掉,使其形式与json类似,然后用demjson把里面的数据转换成列表➕字典的形式
#到这一步,我们也可使用正则或者单独的截取把信息提取来,我这么写是练习技能为主
resp = resp.text.lstrip("var weather_str=").rstrip(";")
'''
正则匹配方法
pattern = re.compile('{ymd:\'(.*?)\',bWendu:\'(.*?)\',yWendu:\'(.*?)\',tianqi:\'(.*?)\',fengxiang:\'(.*?)\',fengli:\'(.*?)\'},',re.S)
resp = re.findall(pattern,resp.text)
'''
提取目标数据
我在这里只提取了日期和温度
#定义数组变量
date_line = []
temp_info = []
#提取数据
for i in weather_info :
#最高温度 温度里面包含特殊符号,这里用正则表达式处理一下
# ^ 以什么开头; [\-|0-9]:\转义负号 |表示或,总体表示 -或 数字0到9; [0-9]:数字0到9 *匹配前面的元符0次或一次
rr = re.compile("^[\-|0-9][0-9]*")
rr = rr.findall(i["bWendu"])
date_line.append(i["ymd"])
temp_info.append(rr[0])
#这样我们就获得了需要用到的数据 嘿嘿
完整版
'''
Created on Feb 12, 2020
@author: sun
'''
import requests
import re
import demjson
#注意事项 当我们import json的时候,它会先搜索json.py所在目录有没有对应的模块,
#由于我们命名的json.py与json模块文件重名,所以会误以为我们自己创建的json.py即为json模块文件,所以会出现这样的错误。
#目标网址 http://tianqi.2345.com/wea_history
# json 文件的位置http://tianqi.2345.com/t/wea_history/js/202002/54511_202002.js
#经过塞选不同的地区发现变化的主要是日期和地区编码
def getWeatherInfo(date_nu,org_code,wen_du):
#构建url
url = 'http://tianqi.2345.com/t/wea_history/js/{date}/{code}_{date}.js'.format(date = date_nu,code = org_code)
#爬取数据
#构造请求头
header_info = {'User-Agent':'Mozilla/5.0 (compatible; WOW64; MSIE 10.0; Windows NT 6.2)'}
resp = requests.get(url,headers = header_info)
#使用requests方法后,会返回一个response对象,其存储了服务器响应的内容,如上实例中已经提到的 r.text、r.status_code……
#获取文本方式的响应体实例:当你访问 r.text 之时,会使用其响应的文本编码进行解码,并且你可以修改其编码让 r.text 使用自定义的编码进行解码。
#get返回的是一个response对象,里面有各种变量,你需要的是其中叫text的那一个。你直接print这个response对象的结果完全取决于开发者对__repr__或者__str__的重写情况。
resp = resp.text.lstrip("var weather_str=").rstrip(";")
#这时已经获取到数据了,也可以用正则或其他方式把数据拆分出来
weather_info = demjson.decode(resp)["tqInfo"] #把列表里面的元素转换成字典
weather_info = [i for i in weather_info if len(i)>0] #因为最后一个是空的,所以这里把空的去掉
#定义数组
date_line = []
temp_info = []
#提取信息
for i in weather_info :
#最高温度 温度里面包含特殊符号,这里用正则表达式处理一下
# ^ 以什么开头; [\-|0-9]:\转义负号 |表示或,总体表示 -或 数字0到9; [0-9]:数字0到9 *匹配前面的元符0次或一次
rr = re.compile("^[\-|0-9][0-9]*")
rr = rr.findall(i[wen_du])
date_line.append(i["ymd"])
temp_info.append(rr[0])
return date_line,temp_info
#print(getWeatherInfo('202001','54511')[0])
#print(getWeatherInfo('202001','54511')[1])
发表评论