zoukankan      html  css  js  c++  java
  • python3爬取墨迹天气并发送给微信好友,附源码

    需求:

    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 = '来自大明明的天气问候
    ' + city + '' + ',' + DATE + '
    '+ '实时温度:' + temp1 + '' + ',' + temp2 + '
    '  '湿度:' + H + '
    ' '风速:' + S + '
    ' '紫外线:' + U +'
    ' '今日提示:' + A + '
    ' +'今日限行:' + F
    27     else:
    28         info = '来自大明明的天气问候
    ' + city + '' + ',' + DATE + '
    '+ '实时温度:' + temp1 + '' + ',' + temp2 + '
    '  '湿度:' + H + '
    ' '风速:' + S + '
    ' '紫外线:' + U +'
    ' '今日提示:' + A
    29 else:
    30     info = '来自大明明的天气问候
    ' + prov +'' + city + '' + ',' + DATE + '
    '+ '实时温度:' + temp1 + '' + ',' + temp2 + '
    '  '湿度:' + H + '
    ' '风速:' + S + '
    ' '紫外线:' + U +'
    ' '今日提示:' + 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 = '
    明日天气:
    ' + '温度:' + temp_t + '
    ' + '风速:' + S_t + '
    ' '空气质量:' + AQI_t + '
    '
    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 +'
    '
    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 = '来自大明明的天气问候
    ' + city + '' + ',' + DATE + '
    '+ '实时温度:' + temp1 + '' + ',' + temp2 + '
    '  '湿度:' + H + '
    ' '风速:' + S + '
    ' '紫外线:' + U +'
    ' '今日提示:' + A + '
    ' +'今日限行:' + F
     49     else:
     50         info = '来自大明明的天气问候
    ' + city + '' + ',' + DATE + '
    '+ '实时温度:' + temp1 + '' + ',' + temp2 + '
    '  '湿度:' + H + '
    ' '风速:' + S + '
    ' '紫外线:' + U +'
    ' '今日提示:' + A
     51 else:
     52     info = '来自大明明的天气问候
    ' + prov +'' + city + '' + ',' + DATE + '
    '+ '实时温度:' + temp1 + '' + ',' + temp2 + '
    '  '湿度:' + H + '
    ' '风速:' + S + '
    ' '紫外线:' + U +'
    ' '今日提示:' + 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 = '
    明日天气:
    ' + '温度:' + temp_t + '
    ' + '风速:' + S_t + '
    ' '空气质量:' + AQI_t + '
    '
     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 +'
    '
     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 = '❤❤❤❤❤❤❤❤❤❤❤
    '+info + '
    ' + 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 = '来自大明明的天气问候 ' + city + '' + ',' + DATE + ' '+ '实时温度:' + temp1 + '' + ',' + temp2 + ' ' '湿度:' + H + ' ' '风速:' + S + ' ' '紫外线:' + U +' ' '今日提示:' + A + ' ' +'今日限行:' + F
    else:
    info = '来自大明明的天气问候 ' + city + '' + ',' + DATE + ' '+ '实时温度:' + temp1 + '' + ',' + temp2 + ' ' '湿度:' + H + ' ' '风速:' + S + ' ' '紫外线:' + U +' ' '今日提示:' + A
    else:
    info = '来自大明明的天气问候 ' + prov +'' + city + '' + ',' + DATE + ' '+ '实时温度:' + temp1 + '' + ',' + temp2 + ' ' '湿度:' + H + ' ' '风速:' + S + ' ' '紫外线:' + U +' ' '今日提示:' + 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 = ' 明日天气: ' + '温度:' + temp_t + ' ' + '风速:' + S_t + ' ' '空气质量:' + AQI_t + ' '
    #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 +' '
    #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 = '❤❤❤❤❤❤❤❤❤❤❤ '+info + ' ' + 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("你要轰炸那个群呀?"))
  • 相关阅读:
    解决:Server IPC version 9 cannot communicate with client version 4
    解决Exception: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
    hadoop解决windows下:Failed to set permissions of path: mp .staging to 0700
    find命令的使用
    linux解决端口冲突问题
    linux中实用的小工具lrzsz
    nginx常用命令
    编写测试用例的方法
    selenium之web自动化模拟操作(窗口,鼠标,键盘,js)
    什么是面向连接服务?什么是无连接服务?它们的区别是什么?
  • 原文地址:https://www.cnblogs.com/aby321/p/9633462.html
Copyright © 2011-2022 走看看