为什么要爬天气?1.可以练手。2、使用itchat库实现自动回复功能后,集成查看天气功能,实现微信自查天气功能!首先,还是类似的套路,看看能不能直接在官网抓包(XHR),获取一个通用的API。然后直接用API查询,好吗?在百度上搜索关键字【天气】或【南京天气】,会弹出相应的网页:http://www.weather.com.cn/weather/101190101.shtml。点进去可以看到对应城市的下周天气:换到另一个城市上海,我们发现浏览器地址变成了:http://www.weather.com.cn/weather/101020100.shtml。原来这串数字101020100对应的是对应城市的代码。下面分析一下页面上的XHR请求,看看有没有直接抓包的可能?Googlebrowser-check-Networt-XHR-refresh后,发现没有XHR请求。看来我们需要的天气内容和城市代码,可能会包含在页面中,经过JS和服务端处理后渲染出来……嗯,尝试失败!再看JS请求,发现太多了,无法一一查看!幸运的是,网上已经有人记录了所有城市对应的城市代码。我复制下来保存到本地mysql。数据在百度云。需要的话可以自己下载。您可以直接通过执行SQL将SQL表和数据一起构建。https://pan.baidu.com/s/1kXaN2Aj密码为:8y6n。好了,准备工作做完了,现在思路很清晰了,国家的城市和代码都有了,我们只需要输入城市就可以从mysql中获取对应的城市代码,比如:101020100,然后构造对应的url:http://www.weather.com.cn/weather/101190101.shtml查看对应城市的7天天气。但是页面没有XHR和直接可用的json数据,所以我们只能自己动手——分析网页内容,写正则表达式/beautifulSoup/Xpath提取页面信息,具体内容不再赘述这里可以参考代码importreimportpymysqlimportrequestsfrombs4importBeautifulSoupclassSearchWeather():def__init__(self):self.HEADERS={'User-Agent':'Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36''(KHTML,likeGecko)Chrome/58.0.3029.110Safari/537.36'}self.CONNECTION=pymysql.connect(host='localhost',user='root',password='xxx',db='xxx',charset='utf8',cursorclass=pymysql.cursors.DictCursor)defgetcityCode(self,cityName):SQL="SELECTcityCodeFROMcityWeatherWHEREcityName='%s'"%cityNametry:withself.CONNECTION.cursor()ascursor:cursor.execute(SQL)self.CONNECTION.commit()结果=cursor.fetchone()returnresult['cityCode']exceptExceptionase:print(repr(e))defgetWeather(self,cityCode,cityname):url='http://www.weather.com.cn/weather/%s.shtml'%cityCodehtml=requests.get(url,headers=self.HEADERS)html.encoding='utf-8'soup=BeautifulSoup(html.text,'lxml')weather="日期天气[温度]风向风力\n"foriteminsoup.find("div",{'id':'7d'}).find('ul').find_all('li'):date,detail=item.find('h1').string,item.find_all('p')title=detail[0].stringtemplow=detail[1].find("i").stringtemphigh=detail[1].find('span').stringifdetail[1].find('span')else''wind,direction=detail[2].find('span')['title'],detail[2].find('i').stringiftemphigh=='':weather+='你好,[%s]今天是:[%s],温度:[%s],%s:[%s]\n'%(cityname,title,templow,wind,direction)else:weather+=(date+title+["+templow+"~"+temphigh+'°C]'+wind+direction+"\n")returnweatherdefmain(self,city):cityCode=self.getcityCode(city)detail=self.getWeather(cityCode,city)print(detail)if__name__=="__main__":weather=SearchWeather()weather.main(city=input('请输入城市名称:'))代码运行效果如下:
