為什麼要爬天氣呢?1.可以練練手2.利用itchat庫實現自動回覆功能後,把查天氣的功能集成起來,實現微信自助查天氣功能! 首先,還是相似的套路,我們看看能不能在官網上直接抓包(XHR)來獲取一個通用API。然後直接用API查詢就OK?在百度搜關鍵詞【天氣】或者【南京天氣】會跳出對應的網頁:http ...
為什麼要爬天氣呢?1.可以練練手2.利用itchat庫實現自動回覆功能後,把查天氣的功能集成起來,實現微信自助查天氣功能!
首先,還是相似的套路,我們看看能不能在官網上直接抓包(XHR)來獲取一個通用API。然後直接用API查詢就OK?在百度搜關鍵詞【天氣】或者【南京天氣】會跳出對應的網頁:http://www.weather.com.cn/weather/101190101.shtml.點進去,可以看到相應城市下一周的天氣情況:
再換一個城市上海,我們發現,瀏覽器地址變為:http://www.weather.com.cn/weather/101020100.shtml。原來101020100這串數字對應著相應城市的代碼。我們來分析下頁面上XHR請求,看看有沒有直接抓包的可能?
經過谷歌瀏覽器——檢查-Networt-XHR-刷新,發現並沒有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來提取頁面信息,具體內容在此就不贅述了,詳見代碼就好:
import re
import pymysql
import requests
from bs4 import BeautifulSoup
class SearchWeather():
def __init__(self):
self.HEADERS ={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ''(KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
self.CONNECTION = pymysql.connect(host='localhost',user='root',password='xxx',db='xxx',charset='utf8',cursorclass=pymysql.cursors.DictCursor)
def getcityCode(self,cityName):
SQL = "SELECT cityCode FROM cityWeather WHERE cityName='%s'" % cityName
try:
with self.CONNECTION.cursor() as cursor:
cursor.execute(SQL)
self.CONNECTION.commit()
result = cursor.fetchone()
return result['cityCode']
except Exception as e:
print(repr(e))
def getWeather(self,cityCode,cityname):
url = 'http://www.weather.com.cn/weather/%s.shtml' % cityCode
html = requests.get(url,headers = self.HEADERS)
html.encoding='utf-8'
soup=BeautifulSoup(html.text,'lxml')
weather = "日期 天氣 【溫度】 風向風力\n"
for item in soup.find("div", {'id': '7d'}).find('ul').find_all('li'):
date,detail = item.find('h1').string, item.find_all('p')
title = detail[0].string
templow = detail[1].find("i").string
temphigh = detail[1].find('span').string if detail[1].find('span') else ''
wind,direction = detail[2].find('span')['title'], detail[2].find('i').string
if temphigh=='':
weather += '你好,【%s】今天白天:【%s】,溫度:【%s】,%s:【%s】\n' % (cityname,title,templow,wind,direction)
else:
weather += (date + title + "【" + templow + "~"+temphigh +'°C】' + wind + direction + "\n")
return weather
def main(self,city):
cityCode = self.getcityCode(city)
detail = self.getWeather(cityCode,city)
print (detail)
if __name__ == "__main__":
weather = SearchWeather()
weather.main(city=input('請輸入城市名稱:'))
代碼運行效果如下: