项目简介
爬取中国天气网的天气信息:http://www.weather.com.cn/textFC/hb.shtml
其中,中国天气网将全国分为华北、东北、华东、华中、华南、西北、西南和港澳台八个大区。网址分别如下:
http://www.weather.com.cn/textFC/hb.shtml
http://www.weather.com.cn/textFC/db.shtml
http://www.weather.com.cn/textFC/hd.shtml
http://www.weather.com.cn/textFC/hz.shtml
http://www.weather.com.cn/textFC/hn.shtml
http://www.weather.com.cn/textFC/xb.shtml
http://www.weather.com.cn/textFC/xn.shtml
http://www.weather.com.cn/textFC/gat.shtml
我们需要获取各个城市的天气基本信息。
项目思路
首先我们发现每个大区的地址是很有规律的,并且很少,我们不需要通过爬虫获取(像以前获取分页那样),只需要把他们放入数组中,用函数获取即可。
省份table分析
然后分析其中一个大区,我们以华北为例,发现每个省份都是单独的一个table表格:
普通的tr:第4个以后的tr
其中,分析每个省份table的函数如下:
# 分析每个省份table def beautiful(res): soup = BeautifulSoup(res.content, 'html.parser') print(soup) tr = soup.find('table', width="100%").find_all('tr') # .find定位到所需数据位置 .find_all查找所有的tr(表格) province = '北京' for j in tr[3:]: # 遍历每一个tr标签,tr标签下属还有td标签 td = j.find_all('td') # 缩小单位到每个td标签 city = td[0].get_text().strip() tianqixianxiang_1 = td[1].get_text().strip() fengxiangfengli_1 = td[2].get_text().strip() zuigaoqiwen = td[3].get_text().strip() tianqixianxiang_2 = td[4].get_text().strip() fengxiangfengli_2 = td[5].get_text().strip() zuidiqiwen = td[6].get_text().strip() res = {'省份':province, '城市': city, '天气现象(白天)': tianqixianxiang_1, '风向风力(白天)': fengxiangfengli_1, '最高气温': zuigaoqiwen, '天气现象(夜间)': tianqixianxiang_2, '风向风力(夜间)': fengxiangfengli_2, '最低气温': zuidiqiwen} print(res)
视频讲解
特殊的tr(第1、2、3个tr)
# 分析每个省份table def beautiful(res): soup = BeautifulSoup(res.content, 'html.parser') print(soup) tr = soup.find('table', width="100%").find_all('tr') # .find定位到所需数据位置 .find_all查找所有的tr(表格) province = '北京' for j in tr[2:2]: # 遍历每一个tr标签,tr标签下属还有td标签 td = j.find_all('td') # 缩小单位到每个td标签 city = td[1].get_text().strip() tianqixianxiang_1 = td[2].get_text().strip() fengxiangfengli_1 = td[3].get_text().strip() zuigaoqiwen = td[4].get_text().strip() tianqixianxiang_2 = td[5].get_text().strip() fengxiangfengli_2 = td[6].get_text().strip() zuidiqiwen = td[7].get_text().strip() res = {'省份':province, '城市': city, '天气现象(白天)': tianqixianxiang_1, '风向风力(白天)': fengxiangfengli_1, '最高气温': zuigaoqiwen, '天气现象(夜间)': tianqixianxiang_2, '风向风力(夜间)': fengxiangfengli_2, '最低气温': zuidiqiwen} print(res) for j in tr[3:]: # 遍历每一个tr标签,tr标签下属还有td标签 td = j.find_all('td') # 缩小单位到每个td标签 city = td[0].get_text().strip() tianqixianxiang_1 = td[1].get_text().strip() fengxiangfengli_1 = td[2].get_text().strip() zuigaoqiwen = td[3].get_text().strip() tianqixianxiang_2 = td[4].get_text().strip() fengxiangfengli_2 = td[5].get_text().strip() zuidiqiwen = td[6].get_text().strip() res = {'省份':province, '城市': city, '天气现象(白天)': tianqixianxiang_1, '风向风力(白天)': fengxiangfengli_1, '最高气温': zuigaoqiwen, '天气现象(夜间)': tianqixianxiang_2, '风向风力(夜间)': fengxiangfengli_2, '最低气温': zuidiqiwen} print(res)
现在第一个省份的爬取已经完成,我们改造一下,新建一个函数 paqu_shengfen_table:
实现爬取大区下的任意省份城市天气
代码
下面的代码已经可以实现爬取任意省份的天气情况:
import re import time from lxml import etree import requests from bs4 import BeautifulSoup headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36', 'Cookie': '' } # 在商品内页中操作 def detail(detail_url, option): url = detail_url res = requests.get(url, headers = headers) paqu_shengfen_table(res) def paqu_shengfen_table(res): soup = BeautifulSoup(res.content, 'html.parser') ######################################################################################################### # 下面的 [1] 可以实现爬取第一个省份table,即天津。 # 如果设置为 [0],则是爬取北京table。 # 如果设置为 [2],则是爬取河北table tr_all = soup.select('.conMidtab2 > table')[1] # .find定位到所需数据位置 .find_all查找所有的tr(表格) ######################################################################################################### tr = tr_all.find_all('tr') shengfen = (tr[2].get_text().split())[0] # print(shengfen) beautiful(res, tr, shengfen) # 分析每个省份table def beautiful(res, tr, shengfen): td = tr[2].find_all('td') # 缩小单位到每个td标签 city = td[1].get_text().strip() tianqixianxiang_1 = td[2].get_text().strip() fengxiangfengli_1 = td[3].get_text().strip() zuigaoqiwen = td[4].get_text().strip() tianqixianxiang_2 = td[5].get_text().strip() fengxiangfengli_2 = td[6].get_text().strip() zuidiqiwen = td[7].get_text().strip() res = {'省份':shengfen, '城市': city, '天气现象(白天)': tianqixianxiang_1, '风向风力(白天)': fengxiangfengli_1, '最高气温': zuigaoqiwen, '天气现象(夜间)': tianqixianxiang_2, '风向风力(夜间)': fengxiangfengli_2, '最低气温': zuidiqiwen} print(res) # 便利普通的tr for j in tr[3:]: # 遍历每一个tr标签,tr标签下属还有td标签 td = j.find_all('td') # 缩小单位到每个td标签 city = td[0].get_text().strip() tianqixianxiang_1 = td[1].get_text().strip() fengxiangfengli_1 = td[2].get_text().strip() zuigaoqiwen = td[3].get_text().strip() tianqixianxiang_2 = td[4].get_text().strip() fengxiangfengli_2 = td[5].get_text().strip() zuidiqiwen = td[6].get_text().strip() res = {'省份':shengfen, '城市': city, '天气现象(白天)': tianqixianxiang_1, '风向风力(白天)': fengxiangfengli_1, '最高气温': zuigaoqiwen, '天气现象(夜间)': tianqixianxiang_2, '风向风力(夜间)': fengxiangfengli_2, '最低气温': zuidiqiwen} print(res) def get_datail_url(url, option): detail(url, option) def start(option): # base_url = 'https://www.guazi.com/zz/honda/o{}/' # urls = [] # for x in range(1, 3): # urls.append(base_url.format(x)) # 对网页进行翻页 url = 'http://www.weather.com.cn/textFC/hb.shtml' get_datail_url(url, option) if __name__ == '__main__': print("正在运行... ... 如果小于1秒,说明程序有误") start(1)
实现爬取一个大区下的所有省份,所有城市天气
基本思路是获取一个大区下有多少省份,使用:
table_nums = soup.select('.lQCity > ul > li').__len__()
table_nums的值为5。
即通过获取ul下有多少个li标签,然后取出个数得到。
代码
代码如下:
import re import time from lxml import etree import requests from bs4 import BeautifulSoup headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36', 'Cookie': '' } # 在商品内页中操作 def detail(detail_url, option): url = detail_url res = requests.get(url, headers = headers) paqu_shengfen_table(res) def paqu_shengfen_table(res): soup = BeautifulSoup(res.content, 'html.parser') # 获取一个大区中有多少省份 print(soup) table_nums = soup.select('.lQCity > ul > li').__len__() for i in range(table_nums): # 爬取每个省份table ######################################################################################################### # 下面的 [1] 可以实现爬取第一个省份table,即天津。 # 如果设置为 [0],则是爬取北京table。 # 如果设置为 [2],则是爬取河北table tr_all = soup.select('.conMidtab2 > table')[i] # .find定位到所需数据位置 .find_all查找所有的tr(表格) ######################################################################################################### tr = tr_all.find_all('tr') shengfen = (tr[2].get_text().split())[0] # print(shengfen) beautiful(res, tr, shengfen) # 分析每个省份table def beautiful(res, tr, shengfen): td = tr[2].find_all('td') # 缩小单位到每个td标签 city = td[1].get_text().strip() tianqixianxiang_1 = td[2].get_text().strip() fengxiangfengli_1 = td[3].get_text().strip() zuigaoqiwen = td[4].get_text().strip() tianqixianxiang_2 = td[5].get_text().strip() fengxiangfengli_2 = td[6].get_text().strip() zuidiqiwen = td[7].get_text().strip() res = {'省份':shengfen, '城市': city, '天气现象(白天)': tianqixianxiang_1, '风向风力(白天)': fengxiangfengli_1, '最高气温': zuigaoqiwen, '天气现象(夜间)': tianqixianxiang_2, '风向风力(夜间)': fengxiangfengli_2, '最低气温': zuidiqiwen} print(res) # 便利普通的tr for j in tr[3:]: # 遍历每一个tr标签,tr标签下属还有td标签 td = j.find_all('td') # 缩小单位到每个td标签 city = td[0].get_text().strip() tianqixianxiang_1 = td[1].get_text().strip() fengxiangfengli_1 = td[2].get_text().strip() zuigaoqiwen = td[3].get_text().strip() tianqixianxiang_2 = td[4].get_text().strip() fengxiangfengli_2 = td[5].get_text().strip() zuidiqiwen = td[6].get_text().strip() res = {'省份':shengfen, '城市': city, '天气现象(白天)': tianqixianxiang_1, '风向风力(白天)': fengxiangfengli_1, '最高气温': zuigaoqiwen, '天气现象(夜间)': tianqixianxiang_2, '风向风力(夜间)': fengxiangfengli_2, '最低气温': zuidiqiwen} print(res) def get_datail_url(url, option): detail(url, option) def start(option): # base_url = 'https://www.guazi.com/zz/honda/o{}/' # urls = [] # for x in range(1, 3): # urls.append(base_url.format(x)) # 对网页进行翻页 url = 'http://www.weather.com.cn/textFC/hb.shtml' get_datail_url(url, option) if __name__ == '__main__': print("正在运行... ... 如果小于1秒,说明程序有误") start(1)
实现爬取除港澳台外所有城市天气
下面我们只需要把所有的大区url写在数组中,分别去调用 get_datail_url 函数即可。
因为 港澳台大区的table表格与前面的都不相同,http://www.weather.com.cn/textFC/gat.shtml
所以我们暂时剔除掉港澳台大区的天气爬取。随后有时间我会完善这只爬虫。
代码
import re import time from lxml import etree import requests from bs4 import BeautifulSoup headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36', 'Cookie': '' } # 在商品内页中操作 def detail(detail_url, option): url = detail_url res = requests.get(url, headers = headers) paqu_shengfen_table(res) def paqu_shengfen_table(res): soup = BeautifulSoup(res.content, 'html.parser') # 获取一个大区中有多少省份 table_nums = soup.select('.lQCity > ul > li').__len__() for i in range(table_nums): # 爬取每个省份table ######################################################################################################### # 下面的 [1] 可以实现爬取第一个省份table,即天津。 # 如果设置为 [0],则是爬取北京table。 # 如果设置为 [2],则是爬取河北table tr_all = soup.select('.conMidtab2 > table')[i] # .find定位到所需数据位置 .find_all查找所有的tr(表格) ######################################################################################################### tr = tr_all.find_all('tr') shengfen = (tr[2].get_text().split())[0] # print(shengfen) beautiful(res, tr, shengfen) # 分析每个省份table def beautiful(res, tr, shengfen): td = tr[2].find_all('td') # 缩小单位到每个td标签 city = td[1].get_text().strip() tianqixianxiang_1 = td[2].get_text().strip() fengxiangfengli_1 = td[3].get_text().strip() zuigaoqiwen = td[4].get_text().strip() tianqixianxiang_2 = td[5].get_text().strip() fengxiangfengli_2 = td[6].get_text().strip() zuidiqiwen = td[7].get_text().strip() res = {'省份':shengfen, '城市': city, '天气现象(白天)': tianqixianxiang_1, '风向风力(白天)': fengxiangfengli_1, '最高气温': zuigaoqiwen, '天气现象(夜间)': tianqixianxiang_2, '风向风力(夜间)': fengxiangfengli_2, '最低气温': zuidiqiwen} print(res) # 便利普通的tr for j in tr[3:]: # 遍历每一个tr标签,tr标签下属还有td标签 td = j.find_all('td') # 缩小单位到每个td标签 city = td[0].get_text().strip() tianqixianxiang_1 = td[1].get_text().strip() fengxiangfengli_1 = td[2].get_text().strip() zuigaoqiwen = td[3].get_text().strip() tianqixianxiang_2 = td[4].get_text().strip() fengxiangfengli_2 = td[5].get_text().strip() zuidiqiwen = td[6].get_text().strip() res = {'省份':shengfen, '城市': city, '天气现象(白天)': tianqixianxiang_1, '风向风力(白天)': fengxiangfengli_1, '最高气温': zuigaoqiwen, '天气现象(夜间)': tianqixianxiang_2, '风向风力(夜间)': fengxiangfengli_2, '最低气温': zuidiqiwen} print(res) def get_datail_url(url, option): detail(url, option) def start(option): urls = ['http://www.weather.com.cn/textFC/hb.shtml', 'http://www.weather.com.cn/textFC/db.shtml', 'http://www.weather.com.cn/textFC/hd.shtml', 'http://www.weather.com.cn/textFC/hz.shtml', 'http://www.weather.com.cn/textFC/hn.shtml', 'http://www.weather.com.cn/textFC/xb.shtml', 'http://www.weather.com.cn/textFC/xn.shtml', 'http://www.weather.com.cn/textFC/gat.shtml' # 港澳台的table跟前面的都不太一样,我们先将其去除。 ] for i in range(0, 7): get_datail_url(urls[i], option) if __name__ == '__main__': print("正在运行... ... 如果小于1秒,说明程序有误") start(1)
参考文献:https://blog.csdn.net/python918/article/details/105030833