参考书籍资料
实践工具、软件
- PyCharm 社区版本
- (可选)fiddler Web调试器
- Python3 开发基础库
- chrome web调试
- Json数据Beautify
python镜像加速
安装包镜像
测试官网很慢,淘宝云或者华为云的很快
下载:wget https://repo.huaweicloud.com/python/3.7.5/Python-3.7.5.tgz
解压:tar -xzvf Python-3.7.5.tgz
cd Python-3.7.5
mkdir /usr/local/python3
./configure –prefix=/usr/local/python3
make
make install
mv /usr/bin/python /usr/bin/python_old2
ln -s /usr/local/python3/bin/python3 /usr/bin/python
python -V
pip包镜像
[global]
index-url = https://repo.huaweicloud.com/repository/pypi/simple
trusted-host = repo.huaweicloud.com
timeout = 120
一、项目目的 weather.com.cn网站中提取24小时温度湿度等信息
如上图,抓取完整中24小时的温度、湿度、降水量、风力风向四个数据。但是原始的数据存储在SVG矢量图中,里面存储的数据,是矢量绘图数据,不是原始的数据,不能直接获取。
相对的,上图中的Span中的数据可以通过Python直接获取。
二、网站分析
仔细阅读网站(实际我用了fiddler进行了网站分析),发现实际的数据,存储在图表显示上面的script代码中,命名为observe24h_data的变量中。
三、简单数据采集 热身
7日的数据,可以很容易在后台源码中找到,可以很容易使用beautiful soup库获取到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #参考 https://blog.csdn.net/hepann44/article/details/77524782 import requests from bs4 import BeautifulSoup url = 'http://www.weather.com.cn/weather/101190101.shtml' # 数据地址,从浏览器(注意不同IP显示不同数据)copy http://www.weather.com.cn/weather1d/101190101.shtml header = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } req = requests.get(url, headers=header) req.encoding='utf-8' soup = BeautifulSoup(req.text,'html.parser') ul_tag= soup.find('ul','t clearfix') # 利用 css 查找 Return only the first child of this Tag matching the given criteria li_tag = ul_tag.findAll('li') for tag in li_tag: print(tag.find('h1')) # 时间tag print(tag.find('h1').string) # 时间 print(tag.find('p','wea').string) # wiea print("高温:" + tag.find('p','tem').find('span').string) print("低温:" + tag.find('p', 'tem').find('i').string) print("_______________ ____________________") |
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <h1>1日(今天)</h1> 1日(今天) 多云 高温:5 低温:-2℃ _______________ ____________________ <h1>2日(明天)</h1> 2日(明天) 多云 高温:7 低温:0℃ ... |
四、 项目数据分析和转换
observe24h_data变量导出分析(JSON.cn的JSON数据分析)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | { "od":{ "od0":"20190101180000",//时间戳 "od1":"南京",//城市 "od2":[ { "od21":"18",//小时 "od22":"2",//温度 "od23":"34", "od24":"东北风",//风向 "od25":"2",//风力 "od26":"0.0",//降水量 "od27":"45",//相对湿度 "od28":""//空气质量 }, { "od21":"17", "od22":"3", "od23":"20", "od24":"北风", "od25":"2", "od26":"0.0", "od27":"39", "od28":"60" }, |
observe24h_data的数据是倒序的,第一个数据是一天后的数据。
原始的天气数据转换成DICT的数据输出.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | def get_orgin_dic_data(): url = 'http://www.weather.com.cn/weather/101190101.shtml' # 数据地址,从浏览器(注意不同IP显示不同数据)copy http://www.weather.com.cn/weather1d/101190101.shtml header = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } req = requests.get(url, headers=header) req.encoding = 'utf-8' soup = BeautifulSoup(req.text, 'html.parser') var24data = soup.findAll('script')[4].string print(var24data) # p = re.compile('var observe24h_data = (.*?);') # m = p.match(var24data) rawdata = var24data.strip('\nvar observe24h_data = ').strip(';') # 获取原始JSON数据 print(rawdata) #jd = json.loads(rawdata) # 其变为json数据 # print(jd['od']) # return json.loads(rawdata) ## 转成dict对象 |
五、数据保存
为了便于数据的分析和保存,数据统一存储到CSV文件。增加个CSV文件的Title,便于数据的理解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | def write_data(data): with open("weatherdata.csv",'a',errors='ignore',newline='') as f : f_csv= csv.writer(f) f_csv.writerow(data) First_Row_Data = [] First_Row_Data.append("城市") First_Row_Data.append("读取时间戳") First_Row_Data.append("时间(h)") First_Row_Data.append("温度") First_Row_Data.append("风向") First_Row_Data.append("风力") First_Row_Data.append("降水量") First_Row_Data.append("相对湿度") write_data(First_Row_Data) weather_raw_24_data = get_orgin_dic_data() |
数据倒序保存到CSV文件中。为了自动获取,每隔固定时间读取数据保存.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | while(True): for item in reversed(weather_raw_24_data["od"]["od2"]): # 数据倒序给出的 row_data=[] row_data.append(weather_raw_24_data["od"]["od1"]) row_data.append(weather_raw_24_data["od"]["od0"]) row_data.append(item['od21']) row_data.append(item['od22']) row_data.append(item['od24']) row_data.append(item['od25']) row_data.append(item['od26']) row_data.append(item['od27']) write_data(row_data) # First_Row_Data.append("城市") # First_Row_Data.append("读取时间戳") # First_Row_Data.append("时间(h)") # First_Row_Data.append("温度") # First_Row_Data.append("风向") # First_Row_Data.append("风力") # First_Row_Data.append("降水量") # First_Row_Data.append("相对湿度") print("【休息中……】") time.sleep(3600) |
结果:
六、完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | #参考 https://blog.csdn.net/u013063099/article/details/73467675 #参考 https://blog.csdn.net/heshushun/article/details/77772408 import requests from bs4 import BeautifulSoup # import re # 正则表达式模块,内置 import json #JSON处理 内置 import csv # 内置CSV包 import time #内置time包 def write_data(data): with open("weatherdata.csv",'a',errors='ignore',newline='') as f : f_csv= csv.writer(f) f_csv.writerow(data) # 1.利用requests获取请求 、BeautifulSoup抓取数据。 # 2.Strip()函数简单处理函数; # 3.JSON库转换成JSON类 def get_orgin_dic_data(): url = 'http://www.weather.com.cn/weather/101190101.shtml' # 数据地址,从浏览器(注意不同IP显示不同数据)copy http://www.weather.com.cn/weather1d/101190101.shtml header = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } req = requests.get(url, headers=header) req.encoding = 'utf-8' soup = BeautifulSoup(req.text, 'html.parser') var24data = soup.findAll('script')[4].string print(var24data) # p = re.compile('var observe24h_data = (.*?);') # m = p.match(var24data) rawdata = var24data.strip('\nvar observe24h_data = ').strip(';') # 获取原始JSON数据 print(rawdata) #jd = json.loads(rawdata) # 其变为json数据 # print(jd['od']) # return json.loads(rawdata) ## 转成dict对象 rawdata = var24data.strip('\nvar observe24h_data = ').strip(';') # 获取原始JSON数据 print(rawdata) #jd = json.loads(rawdata) # 其变为json数据 # print(jd['od']) return json.loads(rawdata) ## 转成dict对象 First_Row_Data = [] First_Row_Data.append("城市") First_Row_Data.append("读取时间戳") First_Row_Data.append("时间(h)") First_Row_Data.append("温度") First_Row_Data.append("风向") First_Row_Data.append("风力") First_Row_Data.append("降水量") First_Row_Data.append("相对湿度") # write_data(First_Row_Data) weather_raw_24_data = get_orgin_dic_data() print(weather_raw_24_data["od"]["od2"]) #print("获取到的原始天气数据:" + weather_raw_24_data[od2]) #print(weather_raw_24_data["od"]["od2"]) while(True): for item in reversed(weather_raw_24_data["od"]["od2"]): # 数据倒序给出的 row_data=[] row_data.append(weather_raw_24_data["od"]["od1"]) row_data.append(weather_raw_24_data["od"]["od0"]) row_data.append(item['od21']) row_data.append(item['od22']) row_data.append(item['od24']) row_data.append(item['od25']) row_data.append(item['od26']) row_data.append(item['od27']) write_data(row_data) # First_Row_Data.append("城市") # First_Row_Data.append("读取时间戳") # First_Row_Data.append("时间(h)") # First_Row_Data.append("温度") # First_Row_Data.append("风向") # First_Row_Data.append("风力") # First_Row_Data.append("降水量") # First_Row_Data.append("相对湿度") print("【休息中……】") time.sleep(3600) |
待续:数据优化
读取的数据有许多重复的。待优化