爬虫对象选择
打开中国天气网站,例如我要爬取厦门近 40 天的天气情况,打开对应的网页。“weather40d”目录是近 40 天的天气,“101230201”是厦门城市的 id。
http://www.weather.com.cn/weather40d/101230201.shtml
打开开发者工具,观察到每一天的天气数据还是比较复杂的,所以我们还是要找 API。
在 network 中观察,Fetch/XHG 中没有任何请求的交互,说明这个网页要么是静态的,要么是用 JavaScript 动态生成的。
随便找一个在页面中的字符串,例如以 11 月 7 号的天气“多云转小雨”为例,可以看到搜索出一个结果。
查看这个 JavaScript 文件,可以看到这里罗列了一系列的数据。
打开详细的数据,发现这个字典里面的数据可以和网页的数据对应,说明这个就是我们想要的 js 文件。
请求头修改
查看这个请求的请求头,得到这个 js 文件的 url。
但是访问这个 url,发现回显 403 错误。403 错误表示资源不可用,也就是服务器理解客户的请求,但拒绝处理它,通常由于服务器上文件或目录的权限设置导致的。
也就是说只有特定的地方发起请求才能获取这个资源,查看请求头,发现 “Referer” 字段的值为中国天气网站。Referer 字段用于告诉服务器该网页是从哪个页面链接过来的,因此很有可能我们想要的 js 文件只接受来源于该网站的请求。
同时还有一个“User-Agent”字段也需要设置,User-Agent 字段会告诉网站服务器访问者是通过什么工具来请求的。如果使用的是爬虫,这个字段会被显式的注明是 Python 爬虫,所以我们要改成浏览器。使用 requests 库的 get 方法,同时夹带头文件进行请求就可以成功。
import requests
url = "http://d1.weather.com.cn/calendar_new/2021/101230201_202111.html"
headers = {
"Referer":"http://www.weather.com.cn/",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
}
r = requests.get(url=url, headers=headers)
print("请求的状态是:" + str(r.status_code))
数据处理
观察 Response 的内容,发现除了开头的 “var fc40 = [”这一串字符串,后面的内容都是以 json 的格式存在的。所以只需要把一开始的 “var fc40 = [”删掉,请求的内容就可以以 JSON 的格式解析。
首先修改编码,然后剔除掉开头的 11 个字符,用 json 库就可以来解析这些数据。会得到一个存有当前页面所有日期的天气数据的 list,每个元素都是一个字典。
import json
content = r.content.decode(encoding='utf-8')
weathers = json.loads(content[11:])
最后就是获取我们需要的数据了,我挑选的数据如下:
字段 | 含义 |
---|---|
date | 日期 |
nlyf | 农历月份 |
nl | 农历日期 |
w1 | 天气 |
wd1 | 风向 |
max | 最高温度 |
min | 最低温度 |
jq | 节气 |
t1 | 温度变化 |
hmax | 历史最高温均值 |
hmin | 历史最低温均值 |
hgl | 历史降雨率 |
alins | 黄历宜 |
als | 黄历忌 |
将这些数据写入 xls 文件,代码如下: |
import xlwt
writebook = xlwt.Workbook()
sheet = writebook.add_sheet('Sheet1')
keys = ['date','nlyf','nl','w1','wd1','max','min','jq','t1','hmax','hmin','hgl','alins','als']
for i in range(len(keys)):
sheet.write(0, i, keys[i])
for i in range(len(weathers)):
for j in range(len(keys)):
sheet.write(i + 1, j, weathers[i][keys[j]])
writebook.save('weathers.xls')
完整代码
爬取厦门地区近 40 天天气预报数据,一个简单的爬虫 demo 如下:
import requests
import json
import xlwt
url = "http://d1.weather.com.cn/calendar_new/2021/101230201_202111.html"
headers = {
"Referer":"http://www.weather.com.cn/",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
}
r = requests.get(url=url, headers=headers)
if r.status_code == 200:
content = r.content.decode(encoding='utf-8')
weathers = json.loads(content[11:])
writebook = xlwt.Workbook()
sheet = writebook.add_sheet('Sheet1')
keys = ['date','nlyf','nl','w1','wd1','max','min','jq','t1','hmax','hmin','hgl','alins','als']
for i in range(len(keys)):
sheet.write(0, i, keys[i])
for i in range(len(weathers)):
for j in range(len(keys)):
sheet.write(i + 1, j, weathers[i][keys[j]])
writebook.save('weathers.xls')
爬取的数据如下所示: