需求:
1. 爬取墨迹天气的信息,包括温湿度、风速、紫外线、限号情况,生活tips等信息
2. 输入需要查询的城市,自动爬取相应信息
3. 链接微信,发送给指定好友
思路比较清晰,主要分两块,一是爬虫,二是用python链接微信(非企业版微信)
先随便观察一个城市的墨迹天气,例如石家庄市的url为“https://tianqi.moji.com/weather/china/hebei/shijiazhuang”,多观察几个城市的url可发现共同点就是,前面的都一样,后面的是以省拼音/市拼音结尾的。当然直辖市两者拼音一样。当然还有一些额外情况,比如山西和陕西,后者的拼音是Shaanxi,这个用户输入的时候注意一下
1 prov = input("请输入省份:")
2 city = input("请输入城市:")
3 pin = Pinyin()
4
5 prov_pin = pin.get_pinyin(prov,'')#将汉字转为拼音
6 city_pin = pin.get_pinyin(city,'')
7
8 url = "https://tianqi.moji.com/weather/china/"
9 url = url + prov_pin +'/'+ city_pin
10 print(url)
将用户输入的省、市与开头不变的做字符串连接,形成需要爬取的完整的url。我这里用户输入的是中文,而url中需要的是拼音,因此安装了第三方库xpinyin
1 #获取天气信息begin#
2
3 htmlData = request.urlopen(url).read().decode('utf-8')
4 soup = BeautifulSoup(htmlData, 'lxml')
5 #print(soup.prettify())
6 weather = soup.find('div',attrs={'class':"wea_weather clearfix"})
7 #print(weather)
8 temp1 = weather.find('em').get_text()
9 temp2 = weather.find('b').get_text()
10 # 使用select标签时,如果class中有空格,将空格改为“.”才能筛选出来
11 # 空气质量AQI
12 AQI = soup.select(".wea_alert.clearfix > ul > li > a > em")[0].get_text()
13 H = soup.select(".wea_about.clearfix > span")[0].get_text()#湿度
14 S = soup.select(".wea_about.clearfix > em")[0].get_text()#风速
15
16 if prov == '北京' or prov == '天津':
17 F = soup.select(".wea_about.clearfix > b")[0].get_text()#查找尾号限行,只有北京、天津有
18
19 A = soup.select(".wea_tips.clearfix em")[0].get_text()#今日天气提示
20 U = soup.select(".live_index_grid > ul > li")[-3].find('dt').get_text() #紫外线强度
21 #print(AQI,H,S,A,U)
22 DATE = str(datetime.date.today())#获取当天日期****-**-**
23
24 if prov == '北京' or prov =='天津' or prov =='上海' or prov =='重庆':
25 if prov == '北京' or prov =='天津':
26 info = '来自大明明的天气问候\n' + city + '市' + ',' + DATE + '\n'+ '实时温度:' + temp1 + '℃' + ',' + temp2 + '\n' '湿度:' + H + '\n' '风速:' + S + '\n' '紫外线:' + U +'\n' '今日提示:' + A + '\n' +'今日限行:' + F
27 else:
28 info = '来自大明明的天气问候\n' + city + '市' + ',' + DATE + '\n'+ '实时温度:' + temp1 + '℃' + ',' + temp2 + '\n' '湿度:' + H + '\n' '风速:' + S + '\n' '紫外线:' + U +'\n' '今日提示:' + A
29 else:
30 info = '来自大明明的天气问候\n' + prov +'省' + city + '市' + ',' + DATE + '\n'+ '实时温度:' + temp1 + '℃' + ',' + temp2 + '\n' '湿度:' + H + '\n' '风速:' + S + '\n' '紫外线:' + U +'\n' '今日提示:' + A
31
32 #print(info)
33
34
35 #获取明日天气
36 tomorrow = soup.select(".days.clearfix ")[1].find_all('li')
37 temp_t = tomorrow[2].get_text().replace('°','℃')+ ',' + tomorrow[1].find('img').attrs['alt']#明日温度
38 S_t1 = tomorrow[3].find('em').get_text()
39 S_t2 = tomorrow[3].find('b').get_text()
40 S_t = S_t1 + S_t2#明日风速
41 AQI_t = tomorrow[-1].get_text().strip()#明日空气质量
42
43 info_t = '\n明日天气:\n' + '温度:' + temp_t + '\n' + '风速:' + S_t + '\n' '空气质量:' + AQI_t + '\n'
44 #print(info_t)
45
46 #获取天气信息结束
有几点注意的是:
1、 尾号限行不是每个城市都有的,需要判断下
2、 直辖市输出的时候,最好不要写成“北京省北京市”,这样很别扭
3. 使用select筛选的的是class名或者id名,注意同级和下一级的书写形式;find和find_all是查找的标签
4. 查找单标签中的内容,例如<img alt=**** src=‘***************************.jpg’>这种,想查alt等号后面的内容,或者src后面的连接,用正则感觉很麻烦
1 #获取生活tips开始
2
3 # url1 = 'https://tianqi.moji.com/'
4 # url3 = '/china/beijing/beijing'
5 #定义一个tips的字典
6 tips_dict = {'cold':'感冒预测','makeup':'化妆指数','uray':'紫外线量','dress':'穿衣指数','car':'关于洗车','sport':'运动事宜'}
7 info_tips = ''
8 for i in list(tips_dict.keys()):
9 url_tips = url.replace('weather',i)
10 #url_tips = url1 + i + url3
11 #print(url_tips)
12 htmlData = request.urlopen(url_tips).read().decode('utf-8')
13 soup = BeautifulSoup(htmlData, 'lxml')
14 tips = soup.select(".aqi_info_tips > dd")[0].get_text()
15 #print(tips)
16 info_tips = info_tips + tips_dict.get(i) + ':' +tips +'\n'
17 #print(info_tips)
18 #获取生活tips结束
生活tips在另外的网页中,可以观察到网页的形式是一样的,只是中间的weather换成了其他,因此写一段做循环就ok了
这里用到了字典是因为输出的时候想用中文做提示
链接微信需要安装第三方库itchat,链接只需要这一句话,很简单。初次链接会弹出二维码,手机扫二维码登陆
#链接微信
itchat.auto_login(hotReload=True)#在一段时间内运行不需要扫二维码登陆
全部代码:
1 """
2 从墨迹天气中获取天气信息,推送给微信好友
3
4 """
5
6 from bs4 import BeautifulSoup
7 from urllib import request
8 import datetime
9 import itchat
10 from xpinyin import Pinyin
11
12 prov = input("请输入省份:")
13 city = input("请输入城市:")
14 pin = Pinyin()
15
16 prov_pin = pin.get_pinyin(prov,'')#将汉字转为拼音
17 city_pin = pin.get_pinyin(city,'')
18
19 url = "https://tianqi.moji.com/weather/china/"
20 url = url + prov_pin +'/'+ city_pin
21 print(url)
22
23 #获取天气信息begin#
24
25 htmlData = request.urlopen(url).read().decode('utf-8')
26 soup = BeautifulSoup(htmlData, 'lxml')
27 #print(soup.prettify())
28 weather = soup.find('div',attrs={'class':"wea_weather clearfix"})
29 #print(weather)
30 temp1 = weather.find('em').get_text()
31 temp2 = weather.find('b').get_text()
32 # 使用select标签时,如果class中有空格,将空格改为“.”才能筛选出来
33 # 空气质量AQI
34 AQI = soup.select(".wea_alert.clearfix > ul > li > a > em")[0].get_text()
35 H = soup.select(".wea_about.clearfix > span")[0].get_text()#湿度
36 S = soup.select(".wea_about.clearfix > em")[0].get_text()#风速
37
38 if prov == '北京' or prov == '天津':
39 F = soup.select(".wea_about.clearfix > b")[0].get_text()#查找尾号限行,只有北京、天津有
40
41 A = soup.select(".wea_tips.clearfix em")[0].get_text()#今日天气提示
42 U = soup.select(".live_index_grid > ul > li")[-3].find('dt').get_text() #紫外线强度
43 #print(AQI,H,S,A,U)
44 DATE = str(datetime.date.today())#获取当天日期****-**-**
45
46 if prov == '北京' or prov =='天津' or prov =='上海' or prov =='重庆':
47 if prov == '北京' or prov =='天津':
48 info = '来自大明明的天气问候\n' + city + '市' + ',' + DATE + '\n'+ '实时温度:' + temp1 + '℃' + ',' + temp2 + '\n' '湿度:' + H + '\n' '风速:' + S + '\n' '紫外线:' + U +'\n' '今日提示:' + A + '\n' +'今日限行:' + F
49 else:
50 info = '来自大明明的天气问候\n' + city + '市' + ',' + DATE + '\n'+ '实时温度:' + temp1 + '℃' + ',' + temp2 + '\n' '湿度:' + H + '\n' '风速:' + S + '\n' '紫外线:' + U +'\n' '今日提示:' + A
51 else:
52 info = '来自大明明的天气问候\n' + prov +'省' + city + '市' + ',' + DATE + '\n'+ '实时温度:' + temp1 + '℃' + ',' + temp2 + '\n' '湿度:' + H + '\n' '风速:' + S + '\n' '紫外线:' + U +'\n' '今日提示:' + A
53
54 #print(info)
55
56
57 #获取明日天气
58 tomorrow = soup.select(".days.clearfix ")[1].find_all('li')
59 #<img alt=***** src="*************************.jpg">标签的查找
60 temp_t = tomorrow[2].get_text().replace('°','℃')+ ',' + tomorrow[1].find('img').attrs['alt']#明日温度
61 S_t1 = tomorrow[3].find('em').get_text()
62 S_t2 = tomorrow[3].find('b').get_text()
63 S_t = S_t1 + S_t2#明日风速
64 AQI_t = tomorrow[-1].get_text().strip()#明日空气质量
65
66 info_t = '\n明日天气:\n' + '温度:' + temp_t + '\n' + '风速:' + S_t + '\n' '空气质量:' + AQI_t + '\n'
67 #print(info_t)
68
69 #获取天气信息结束
70
71
72 #获取生活tips开始
73
74 # url1 = 'https://tianqi.moji.com/'
75 # url3 = '/china/beijing/beijing'
76 #定义一个tips的字典
77 tips_dict = {'cold':'感冒预测','makeup':'化妆指数','uray':'紫外线量','dress':'穿衣指数','car':'关于洗车','sport':'运动事宜'}
78 info_tips = ''
79 for i in list(tips_dict.keys()):
80 url_tips = url.replace('weather',i)
81 #url_tips = url1 + i + url3
82 #print(url_tips)
83 htmlData = request.urlopen(url_tips).read().decode('utf-8')
84 soup = BeautifulSoup(htmlData, 'lxml')
85 tips = soup.select(".aqi_info_tips > dd")[0].get_text()
86 #print(tips)
87 info_tips = info_tips + tips_dict.get(i) + ':' +tips +'\n'
88 #print(info_tips)
89 #获取生活tips结束
90
91
92
93
94 #链接微信
95 itchat.auto_login(hotReload=True)#在一段时间内运行不需要扫二维码登陆
96 #给自己的文件助手filehelper发送信息,此时无需访问通讯录
97 #itchat.send('❤来自大明明的天气问候❤',toUserName='filehelper')
98
99 #I = itchat.search_friends()# 获取自己的信息,返回自己的属性字典
100 #friends = itchat.get_friends(update=True)#返回值类型<class 'itchat.storage.templates.ContactList'>。可以看做是列表,列表里的每个元素是一个字典,对应一个好友信息
101 #userName=itchat.search_friends(userName='@b895b018931614e8d30a16b15a8db2da')# 获取特定UserName的用户信息,列表
102 info_all = '❤❤❤❤❤❤❤❤❤❤❤\n'+info + '\n' + info_tips + info_t + '❤❤❤❤❤❤❤❤❤❤❤'
103 print(info_all)
104
105 #发送微信个人
106 def sendToPerson(nickName):
107 user = itchat.search_friends(name=nickName)# 使用备注名或者昵称搜索,微信号不行;若有重名的则全部返回,列表
108 #print(user)
109 userName = user[0]['UserName']
110 itchat.send(info_all, toUserName=userName)
111 print('succeed')
112
113
114
115 #发送微信群
116 def sendToRoom(nickName):
117 user = itchat.search_chatrooms(name=nickName)# 支持模糊匹配
118 #print(user)
119 userName = user[0]['UserName']
120 itchat.send(info_all, toUserName=userName)
121 print('succeed')
122
123
124 sendToPerson(input("你要问候哪位小宝贝呀?"))
125 sendToRoom(input("你要轰炸那个群呀?"))
微信中的显示:
需要改进之处:
1. 有些地名url和汉字拼音不是匹配的,例如齐齐哈尔,拼音是qiqihaer,但是url中是qiqihar,这种情况很多。因此最好是提前有对应的字典
2. 微信无法长连接,过一段时间就会退出,没法做到每日定时推送
3. 本程序只做到了市一层,墨迹天气还可以在细分到下面的区,这里更需要中国城区字典的支持
"""
从墨迹天气中获取天气信息,推送给微信好友
"""
from bs4 import BeautifulSoup
from urllib import request
import datetime
import itchat
from xpinyin import Pinyin
prov = input("请输入省份:")
city = input("请输入城市:")
pin = Pinyin()
prov_pin = pin.get_pinyin(prov,'')#将汉字转为拼音
city_pin = pin.get_pinyin(city,'')
url = "https://tianqi.moji.com/weather/china/"
url = url + prov_pin +'/'+ city_pin
print(url)
#获取天气信息begin#
htmlData = request.urlopen(url).read().decode('utf-8')
soup = BeautifulSoup(htmlData, 'lxml')
#print(soup.prettify())
weather = soup.find('div',attrs={'class':"wea_weather clearfix"})
#print(weather)
temp1 = weather.find('em').get_text()
temp2 = weather.find('b').get_text()
# 使用select标签时,如果class中有空格,将空格改为“.”才能筛选出来
# 空气质量AQI
AQI = soup.select(".wea_alert.clearfix > ul > li > a > em")[0].get_text()
H = soup.select(".wea_about.clearfix > span")[0].get_text()#湿度
S = soup.select(".wea_about.clearfix > em")[0].get_text()#风速
if prov == '北京' or prov == '天津':
F = soup.select(".wea_about.clearfix > b")[0].get_text()#查找尾号限行,只有北京、天津有
A = soup.select(".wea_tips.clearfix em")[0].get_text()#今日天气提示
U = soup.select(".live_index_grid > ul > li")[-3].find('dt').get_text() #紫外线强度
#print(AQI,H,S,A,U)
DATE = str(datetime.date.today())#获取当天日期****-**-**
if prov == '北京' or prov =='天津' or prov =='上海' or prov =='重庆':
if prov == '北京' or prov =='天津':
info = '来自大明明的天气问候\n' + city + '市' + ',' + DATE + '\n'+ '实时温度:' + temp1 + '℃' + ',' + temp2 + '\n' '湿度:' + H + '\n' '风速:' + S + '\n' '紫外线:' + U +'\n' '今日提示:' + A + '\n' +'今日限行:' + F
else:
info = '来自大明明的天气问候\n' + city + '市' + ',' + DATE + '\n'+ '实时温度:' + temp1 + '℃' + ',' + temp2 + '\n' '湿度:' + H + '\n' '风速:' + S + '\n' '紫外线:' + U +'\n' '今日提示:' + A
else:
info = '来自大明明的天气问候\n' + prov +'省' + city + '市' + ',' + DATE + '\n'+ '实时温度:' + temp1 + '℃' + ',' + temp2 + '\n' '湿度:' + H + '\n' '风速:' + S + '\n' '紫外线:' + U +'\n' '今日提示:' + A
#print(info)
#获取明日天气
tomorrow = soup.select(".days.clearfix ")[1].find_all('li')
#<img alt=***** src="*************************.jpg">标签的查找
temp_t = tomorrow[2].get_text().replace('°','℃')+ ',' + tomorrow[1].find('img').attrs['alt']#明日温度
S_t1 = tomorrow[3].find('em').get_text()
S_t2 = tomorrow[3].find('b').get_text()
S_t = S_t1 + S_t2#明日风速
AQI_t = tomorrow[-1].get_text().strip()#明日空气质量
info_t = '\n明日天气:\n' + '温度:' + temp_t + '\n' + '风速:' + S_t + '\n' '空气质量:' + AQI_t + '\n'
#print(info_t)
#获取天气信息结束
#获取生活tips开始
# url1 = 'https://tianqi.moji.com/'
# url3 = '/china/beijing/beijing'
#定义一个tips的字典
tips_dict = {'cold':'感冒预测','makeup':'化妆指数','uray':'紫外线量','dress':'穿衣指数','car':'关于洗车','sport':'运动事宜'}
info_tips = ''
for i in list(tips_dict.keys()):
url_tips = url.replace('weather',i)
#url_tips = url1 + i + url3
#print(url_tips)
htmlData = request.urlopen(url_tips).read().decode('utf-8')
soup = BeautifulSoup(htmlData, 'lxml')
tips = soup.select(".aqi_info_tips > dd")[0].get_text()
#print(tips)
info_tips = info_tips + tips_dict.get(i) + ':' +tips +'\n'
#print(info_tips)
#获取生活tips结束
#链接微信
itchat.auto_login(hotReload=True)#在一段时间内运行不需要扫二维码登陆
#给自己的文件助手filehelper发送信息,此时无需访问通讯录
#itchat.send('❤来自大明明的天气问候❤',toUserName='filehelper')
#I = itchat.search_friends()# 获取自己的信息,返回自己的属性字典
#friends = itchat.get_friends(update=True)#返回值类型<class 'itchat.storage.templates.ContactList'>。可以看做是列表,列表里的每个元素是一个字典,对应一个好友信息
#userName=itchat.search_friends(userName='@b895b018931614e8d30a16b15a8db2da')# 获取特定UserName的用户信息,列表
info_all = '❤❤❤❤❤❤❤❤❤❤❤\n'+info + '\n' + info_tips + info_t + '❤❤❤❤❤❤❤❤❤❤❤'
print(info_all)
#发送微信个人
def sendToPerson(nickName):
user = itchat.search_friends(name=nickName)# 使用备注名或者昵称搜索,微信号不行;若有重名的则全部返回,列表
#print(user)
userName = user[0]['UserName']
itchat.send(info_all, toUserName=userName)
print('succeed')
#发送微信群
def sendToRoom(nickName):
user = itchat.search_chatrooms(name=nickName)# 支持模糊匹配
#print(user)
userName = user[0]['UserName']
itchat.send(info_all, toUserName=userName)
print('succeed')
sendToPerson(input("你要问候哪位小宝贝呀?"))
sendToRoom(input("你要轰炸那个群呀?"))
来源:oschina
链接:https://my.oschina.net/u/4313009/blog/3829682