本次实验中使用到的数据来自链接: http://www.tianqihoubao.com/lishi/,选择的城市是广西来宾,将会用到2011年至2021年的数据,机器学习的框架是tensorflow2.3.0。
1.数据爬取
首先我们得把数据抓取下来,这里将用到python爬虫中最常见的requests库和BeautifulSoup库,下面是数据爬取的craw.py
import requests
from bs4 import BeautifulSoup
import numpy as np
import pandas as pd
import re
def data_list(numpy):
z = []
for i in numpy:
if i.string is not None:
z.append(i.string)
for m, n in enumerate(z):
z[m] = n.replace('\n', '').replace(' ', '')
return z
class Grab:
def __init__(self, url):
self.url = url
self.header = {
'User-Agent': r'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, '
r'like Gecko) Chrome/101.0.4951.41 Safari/537.36 Edg/101.0.1210.32'}
def analysis(self):
for i in range(3):
try:
resp = requests.get(url=self.url, headers=self.header,
proxies=None, timeout=(3, 7))
if resp.status_code == 200:
break
except:
print('请求超时!')
resp.encoding = 'gbk'
html = BeautifulSoup(resp.text, 'html5lib')
return html
def location(self, str1):
text = self.analysis()
data = text.find_all(str1)
return data
def data(self):
data = self.location('td')
data = data_list(data)
data = np.array(data).reshape(-1, 3)
data_date = self.date()
data = np.c_[data_date, data]
print(data)
return data
def date(self):
date = self.location('a')
date = data_list(date)
data_str = ''.join(date)
date = re.findall(r'\d\d\d\d年\d\d月\d\d日', data_str)
return date
if __name__ == "__main__":
flag = 0
for i in range(2011, 2021 + 1):
for j in range(1, 13):
ur = r'http://www.tianqihoubao.com/lishi/laibin/month/{}{:0>2}.html'.format(i, j)
a = Grab(ur)
b = a.data()
if flag == 0:
weather = b.copy()
flag += 1
else:
weather = np.r_[weather, b]
if i == 2022:
if j == 5:
break
c = ['日期', '天气', '气温', '风力风向']
df = pd.DataFrame(data=weather, columns=c)
df.to_csv('data.csv', header=True, index=False, encoding='gbk')
下面说一下思路:
这个网站对于每一个月的数据都会做成一个网页,而且格式也是固定的形式,这样我们只需要两个for循环就能得到所有想要的网页网址
for i in range(2011, 2021 + 1):
for j in range(1, 13):
ur = r'http://www.tianqihoubao.com/lishi/laibin/month/{}{:0>2}.html'.format(i, j)
format是格式化输入,用于控制输入的年份和月份,由于有些月份前面会带一个0,所以这里使用了{:0>2}来让每个数字都左对齐两位。
下面进入到Grab类,初始化从循环中得到的网址和请求头。
def __init__(self, url):
self.url = url
self.header = {
'User-Agent': r'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, '
r'like Gecko) Chrome/101.0.4951.41 Safari/537.36 Edg/101.0.1210.32'}
请求头可以去百度一下常用的即可。
接下来就是请求访问了,调用requests库中的get方法(这里由于这个网址有时会请求失败导致一直卡住,所以设置了一个for循环来多次进行请求访问),get中timeout=(3,7)表示连接时间为3,响应时间为7,使用得当可以提高访问速度,节省时间。resp.status_code根据自己实际访问的网页来填写,编码使用汉字最常见的gbk,最终再使用BeautifulSoup根据html5lib格式来解析即可得到一个类似其实就是 json格式的文本。
def analysis(self):
for i in range(3):
try:
resp = requests.get(url=self.url, headers=self.header,
proxies=None, timeout=(3, 7))
if resp.status_code == 200:
break
except:
print('请求超时!')
resp.encoding = 'gbk'
html = BeautifulSoup(resp.text, 'html5lib')
return html
将得到的文本复制到记事本里分析一下
想要的数据的标签都在td里,但是时间轴却在a里。那我们先对数据动手,为了方便下面多次访问不同的标签,写了一个可以多次调用的访问函数
def location(self, str1):
text