python爬取天气后报网
前言
大二下学期的大数据技术导论课上由于需要获取数据进行分析,我决定学习python爬虫来获取数据。由于对于数据需求量相对较大,我最终选择爬取
天气后报网,该网站可以查询到全国各地多年的数据,而且相对容易爬取。
需求分析:
(1)需要得到全国各大城市的历史天气数据集。
(2)每条天气信息应该包含的内容包括城市名、日期、温度、天气、风向。
(3)以城市名分类,按日期存储在可读的文件中。
(4)存储信息类型应该为字符型。
整体解决方案:
第一步:选择适合进行信息爬虫的网页。
第二步:对该网页相关信息所在的url进行获取。
第三步:通过解析url对应的网页获取信息并存储。
详细解决方案:
第一步:选择适合进行信息爬虫的网页。
(1)由于要获取的是历史天气信息,我们不考虑常见的天气预报网页,最后选择了“天气后报网”作为目标网站。如下图,该网站天气信息按条分布,符合我们的爬虫需求。
(2)我们查看了该网站的robots协议,通过输入相关网址,我们没有找到robots.txt的相关文件,说明该网站允许任何形式的网页爬虫。
(3)我们查看了该类网页的源代码,如下图所示,发现其标签较为清晰,不存在信息存储混乱情况,便于爬取。
第二步:对该网页相关信息所在的url进行获取。
(1)对网页的目录要清晰的解析
为了爬取到全年各地各个月份每一天的所有天气信息,我们小组首先先对网页的层次进行解析,发现网站大体可以分为三层,第一层是地名的链接,通向各个地名的月份链接页面,第二层是月份链接,对应各个网页具体天数,第三个层次则是具体每一天的天气信息,与是我们本着分而治之的原则,对应不同网页的不同层次依次解析对应的网页以获取我们想要的信息。
天气后报网的第一层层次-地名链接
天气后报网第二层次-时间链接
天气后报第三层次具体时间的信息
(1)解析地名网页层次结构-获取地名链接
第一个层次的网页代码
进过观察第一个层次的网页代码,我们发现我们要提取的地名链接在class=”citychk”的div标签的子孙节点<a>标签的href的属性中,于是我们调用beutifulsoup库的findall()方法将a标签以及它的内容放到一个集合中,依次遍历将对应的链接写道web_link.txt文件中。
解析地名链接的核心代码
成功爬取的第一部分地名的链接
(2)解析地名网页层次结构-获取月份链接
进过我们观察发现,我们想要的月份链接存储在class=”box_pcity”的div标签下的li内的a标签的href属性内,于是我们采用同样的方法,依次遍历提取我们想要的月份链接,并按照不同的地名,保存在对应地名的文件中。
第三步:通过解析url对应的网页获取信息并存储。
(1)设置请求登录网页功能,根据不同的url按址访问网页,若请求不成功,抛出HTTPError异常。
(2)设置获取数据功能,按照网页源代码中的标签,设置遍历规则,获取每条数据。注意设置“encoding=‘gb18030’”,改变标准输出的默认编码, 防止控制台打印乱码。
(3)设置文件存储功能,将爬取的数据按年份和月份分类,分别存储在不同的CSV文件中。注意文件名的设置为城市名加日期,方便后期整理。
4. 程序流程图
5. 运行测试截图
(1)url获取
(2)解析网页
附录代码:
爬虫部分代码
-------------------------------------------------------
get_all_city_info.py文件是为了获取每个地方按照月份的链接的代码
get_city_weather_link.py是为了获取地名连接的代码
get_city_weather_content.py是为了获取具体信息的代码
get_all_city_info.py
import urllib.request
import urllib.parse
from bs4 import BeautifulSoup
import os def get_city_link():#将读取到的文件转化为字典
web_link={}
f=open('web_link.txt')
line=f.readline()
while line:
split_line=line.split(',')
key=split_line[0]
value=split_line[1]
value=value.replace('\n','')
web_link[key]=value
line=f.readline() f.close()
return web_link def get_place_name(web_link):#得到所有的地名
place=[]
for key in web_link:
place.append(key)
return place def get_html(url):#依次访问这些网站得到这些网站的html代码
header = {
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'
}
# 伪装浏览器
request = urllib.request.Request(url, headers=header)
response = urllib.request.urlopen(request)
html = response.read()
soup=BeautifulSoup(html,'html.parser')
pretty_html=soup.prettify()
return pretty_html def resolve_html(html,city):
dict={}
soup=BeautifulSoup(html,'html.parser')
for div in soup.find_all('div',class_='box pcity'):
for a in div.find_all('a'):
new_time=''
link='http://www.tianqihoubao.com'+a.attrs['href']
time=str(a.string)
for i in range(len(time)):
if time[i]!=' ' and time[i]!='\n':
new_time=new_time+time[i]
if time.find(city)>=0:
dict[new_time]=link
return dict def trans_dict_to_file(dict,city,file_path):#将爬取到的网址依次存放到文件中
file_path=file_path+city+'.txt'
for key in dict:
with open(file_path,'a') as f:
f.write(key+','+dict[key]+'\n') def main():
path='D:\\face\weatherspider\\time_link\\' web_link=get_city_link()
citys=get_place_name(web_link)
count=0
for city in citys:
try:
count=count+1
print("正在抓取第%d个页面..."%(count))
html=get_html(web_link[city])#获取该城市的页面
print("抓取第%d个页面成功!"%(count))
keyword=city+'天气'
print('正在解析%d个网页...'%(count))
dict=resolve_html(html,keyword)
trans_dict_to_file(dict,city,path)
print('解析第%d个网页成功!'%(count))
except:
continue main()
get_city_weather_content.py
# coding=utf-8
import io
import sys
import requests
from bs4 import BeautifulSoup
import numpy as np
import pandas as pd
import csv
import time
import urllib sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='gb18030') # 改变标准输出的默认编码, 防止控制台打印乱码 def get_soup(year, month):
url = 'http://www.tianqihoubao.com/lishi/' + 'changzhou/' + 'month' + '/' + str(year) + str(month) + '.html'
try:
r = requests.get(url, timeout=30)
r.raise_for_status() # 若请求不成功,抛出HTTPError 异常
# r.encoding = 'gbk'
soup = BeautifulSoup(r.text, 'lxml')
return soup
except HTTPError:
return "Request Error" def saveTocsv(data, fileName):
'''
将天气数据保存至csv文件
'''
result_weather = pd.DataFrame(data, columns=['date', 'tq', 'temp', 'wind'])
result_weather.to_csv(fileName, index=False, encoding='gbk')
print('Save all weather success!') def get_data():
soup = get_soup(year, month)
all_weather = soup.find('div', class_="wdetail").find('table').find_all("tr")
data = list()
for tr in all_weather[1:]:
td_li = tr.find_all("td")
for td in td_li:
s = td.get_text()
data.append("".join(s.split())) res = np.array(data).reshape(-1, 4)
return res if __name__ == '__main__':
years = ['','','','','','','','','']
months = ['','','','','','','','','','','',''] for year in years:
for month in months:
data = get_data()
saveTocsv(data, '常州'+str(year)+str(month)+'.csv')
get_city_weather_link.py
import urllib.request
import urllib.parse
from bs4 import BeautifulSoup def get_html(url):
header = {
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'
}
# 伪装浏览器
request = urllib.request.Request(url, headers=header)
response = urllib.request.urlopen(request)
html = response.read()
return html def main():
url = 'http://www.tianqihoubao.com/lishi/index.htm'
html = get_html(url)
pretty_html=parse_home_page(html)
get_city_link(pretty_html) def parse_home_page(html):
#将网页熬成一锅汤
soup=BeautifulSoup(html,'html.parser')
pretty_html=soup.prettify()
return pretty_html def get_city_link(html):
website={}
url='http://www.tianqihoubao.com'
soup=BeautifulSoup(html,'html.parser')
div_city=soup.find_all('div',class_='citychk')
city_html=str(div_city[0])
city_soup=BeautifulSoup(city_html,'html.parser')
for k in city_soup.find_all('a'):
index=return_index(k['title'])
place=k['title'][0:index]
website[place]=url+k['href']
for key in website:#将各地天气链接存到文件中
with open('web_link.txt','a') as f:
f.write(key+','+website[key]+'\n') def return_index(s):
for i in range(len(s)):
if s[i]=='历':
break
return i main()
python爬取天气后报网的更多相关文章
- 毕设之Python爬取天气数据及可视化分析
写在前面的一些P话:(https://jq.qq.com/?_wv=1027&k=RFkfeU8j) 天气预报我们每天都会关注,我们可以根据未来的天气增减衣物.安排出行,每天的气温.风速风向. ...
- (python爬取小故事网并写入mysql)
前言: 这是一篇来自整理EVERNOTE的笔记所产生的小博客,实现功能主要为用广度优先算法爬取小故事网,爬满100个链接并写入mysql,虽然CS作为双学位已经修习了三年多了,但不仅理论知识一般,动手 ...
- Python爬取中国票房网所有电影片名和演员名字,爬取齐鲁网大陆所有电视剧名称
爬取CBO中国票房网所有电影片名和演员名字 # -*- coding: utf-8 -*- # 爬取CBO中国票房网所有电影片名 import json import requests import ...
- python爬取斗图网中的 “最新套图”和“最新表情”
1.分析斗图网 斗图网地址:http://www.doutula.com 网站的顶部有这两个部分: 先分析“最新套图” 发现地址栏变成了这个链接,我们在点击第二页 可见,每一页的地址栏只有后面的pag ...
- 适合初学者的Python爬取链家网教程
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: TinaLY PS:如有需要Python学习资料的小伙伴可以加点击下 ...
- Python 爬取煎蛋网妹子图片
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2017-08-24 10:17:28 # @Author : EnderZhou (z ...
- python爬取中国知网部分论文信息
爬取指定主题的论文,并以相关度排序. #!/usr/bin/python3 # -*- coding: utf-8 -*- import requests import linecache impor ...
- python爬取千库网
url:https://i588ku.com/beijing/0-0-default-0-8-0-0-0-0-1/ 有水印 但是点进去就没了 这里先来测试是否有反爬虫 import requests ...
- Python爬取猪肉价格网并获取Json数据
场景 猪肉价格网站: http://zhujia.zhuwang.cc/ 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获 ...
随机推荐
- UVA 11346 Possibility
#include<bits/stdc++.h> #include<stdio.h> #include<iostream> #include<cmath> ...
- cogs157. [USACO Nov07] 奶牛跨栏 x
157. [USACO Nov07] 奶牛跨栏 ★★ 输入文件:hurdles.in 输出文件:hurdles.out 简单对比时间限制:1 s 内存限制:128 MB 译 by Cm ...
- JavaWeb_(Jar)使用fastjson解析json和序列化对象
菜鸟教程 传送门 JSON官网 传送门 fastjson插件下载 传送门 序列化[百度百科]:序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对 ...
- pip & conda 换源
conda换源方法具体参考清华大学镜像站Anaconda 镜像使用帮助 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn ...
- spring的AOP基本原理
一.什么是AOP AOP(Aspect Oriented Programming),意思是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP基于IoC基础,是对OOP ...
- note: Spanner: Google’s Globally-Distributed Database
1. Abstract & introduction ref:http://static.googleusercontent.com/media/research.google.com/zh- ...
- mesh之孔洞检测
mesh之孔洞检测 图1 检测孔洞点 图2 检测孔洞点 图3 检测孔洞点 图4 细节
- golang RPC通信读写超时设置
golang RPC通信中,有时候就怕读写hang住. 那是否可以设置读写超时呢? 1.方案一: 设置连接的读写超时 1.1 client RPC通信基于底层网络通信,可以通过设置connection ...
- leetcode -1 count the path
- 创建一个包含TC的Alpine镜像
镜像的创建 更换镜像至ustc(为了测试时的速度) 安装musl-dev make gcc linux-headers bison flex以使TC可以编译 拷贝进TC的源代码 进入源代码文件夹进行编 ...