天气后报网——数据爬取(多线程)
一、爬取数据
1.确定爬虫要获取的数据
2016年-2020年全国363个城市每天的天气情况(城市名、日期、天气状况、气温、风力风向)
2.爬取的网站
天气后报网(http://www.tianqihoubao.com/lishi)
3.要使用的技术
(网络库lrequests)、(分析库lxml、BeautifulSoup)、(存储csv)、(多线程queue)
4.分析待抓取数据的网站
1)打开天气后报网(http://www.tianqihoubao.com/lishi),获取每个城市的超链接,在网页中右击->检查->Ctrl+Shift+C+点击北京
发现<div class="citychk">标签下的<dd>标签下的a标签href属性中包含了相关城市的链接,点击该链接
分析url:http://www.tianqihoubao.com+a标签的href属性,故可使用map()方法和lamdba函数构造每个城市的url
1 city_urls = html.xpath("//div[@class='citychk']//dd//a/@href")
2 city_urls = list(map(lambda url: "http://www.tianqihoubao.com"+url, city_urls))
点击2016年1月北京天气,观察并分析url
可以在城市url的基础上使用双重for循环构造详情页面的url:http://www.tianqihoubao.com/listhi/beijing/month/+年份+月份+.html
1 for url_city in url_citys:
2 url = url_city.replace('.html', '/month/{}{:0>2d}.html')
3 for year in range(2016,2021):
4 for month in range(1, 13):
5 details_url=url.format(year,month)
2)分析详情页面以(http://www.tianqihoubao.com/lishi/beijing/month/201601.html)为例
在网页中右击->检查->Ctrl+Shift+C+点击2016年01月01日
从第二个<tr>标签开始,<tr>标签下4个<td>标签中的信息分别为日期、天气状况、气温、风力风向
由于获取的字符串中前、后、中间都有空白字符,故使用join()方法拼接字符串
1 trs = soup.find_all("tr")[1:]
2 for tr in trs:
3 tds = tr.find_all("td")
4 data = ''.join(list(tds[0].stripped_strings)[0].split())
5 state = ''.join(list(tds[1].stripped_strings)[0].split())
6 temp = ''.join(list(tds[2].stripped_strings)[0].split())
7 wind = ''.join(list(tds[3].stripped_strings)[0].split())
使用<h2>中的文本作为csv表名和城市名
1 # 城市名
2 city = list(soup.find('div',attrs={"id":"s-calder","class":"box"}).stripped_strings)[0]
3 city_name = ''.join(re.findall(r'[^0-9]',city))[:-9] # 使用正则表达式除去数字的目的是防止月份的干扰
1 # csv表的路径
2 path = "D:\\2016-2020全国地级市天气(月)\\"+city[:-4]+'.csv'
5.爬虫程序:
1)爬取数据.py 普通的爬虫程序(以城市位单位,最终获得363张csv表) 虽然设置了随机请求头和延时,但是由于需要发送21780次url请求,还是很容易造成([WinError 10054] 远程主机强迫关闭了一个现有的连接)错误,导致程序退出,因此提供了改进的版本(多线程爬虫)
2)爬取数据多线程.py 多线程爬虫程序(以月份为单位,最终获得21780张csv表)
优点: 虽然无法避免[WinError 10054]错误,但是即使发生了,也只是会退出那一个线程,而不会导致整个程序的退出,而且在效率上是上面的六倍左右
缺点: 发生错误的线程将无法获取该线程内url的数据,造成数据缺失,因此提供了(查找缺失数据并重构url.py),查找出有缺失数据的城市,并且重构城市url,可以将print(lack_data_url)出的列表返回(爬取数据多线程.py),最终获得完整的数据。
二、数据整合
1、数据整合(城市).py 将以月份为单位的21780张csv表整合成以城市为单位的363张csv表
2、数据整合(大汇总).py 将以城市为单位的363张csv表汇总到1张csv表中(2016-2020全国地级市天气大汇总.zip,由于文件超过25Mb,故只能将其压缩)
以上所有代码皆可在本人github账号上下载: https://github.com/chyhoo/2016-2020Chinese-Weather-Analysis