一、Python環境搭建
下載安裝python
https://www.python.org/downloads/
下載安裝PyCharm,Community版即可
https://www.jetbrains.com/pycharm/download/#section=windows
理論上應該先安裝python再安裝IDE(PyCharm),必要時按網上要求進行環境變量設置。
二、爬蟲背景知識
1.網頁結構簡介
網頁一般由三部分組成:HTML(超文本標記語言)、CSS(層疊樣式表)和JScript(活動腳本語言)。
其中,HTML相當於網頁的結構框架,查看網頁源代碼時,可見大量成對出現的HTML標簽“<>”,如下所示:
<html>..</html> 表示標記中間的元素是網頁 <body>..</body> 表示用戶可見的內容 <div>..</div> 表示框架 <p>..</p> 表示段落 <li>..</li>表示列表 <img>..</img>表示圖片 <h1>..</h1>表示標題 <a href="">..</a>表示超鏈接
CSS定義元素外觀及修飾效果,JScript負責實現交互功能及特效。
2. 爬蟲合法性

選擇“Project Interpreter”(項目編譯器)命令,確認當前選擇的編譯器,然后單擊右上角的加號
以requests為例,其他與之相同。在搜索框輸入:requests(一定要輸入完整),然后單擊左下角的“Install Package”
安裝完成后,會在 Install Package 上顯示“Package‘requests’ installed successfully”
2. 代碼分析
以順德區為例,進入中國氣象台網:http://www.nmc.cn/publish/forecast/AGD/shunde.html,在5月21日11:00降水量(2.8mm)處單擊右鍵 > 檢查
此時會顯示出開發者見面,高亮處標示元素即為檢查元素(2.8mm),對其右鍵 > Copy > Copy selector
復制內容如下:
#day0 > div:nth-child(1) > div:nth-child(3)
使用 soup.select 引用這個路徑,代碼如下:
1 import requests # 加載 requests 庫,用於網頁獲取 2 from bs4 import BeautifulSoup # 加載 BeautifulSoup 庫,用於解析獲取的網頁 3 4 url = 'http://www.nmc.cn/publish/forecast/AGD/shunde.html' # 中央氣象台網順德區預報網頁 5 strHtml = requests.get(url) 6 strHtml.encoding = strHtml.apparent_encoding # 指定源網頁編碼方式作為文字解碼方式 7 soup = BeautifulSoup(strHtml.text, 'lxml') 8 data = soup.select('#day0 > div:nth-child(1) > div:nth-child(3)') # 將 Copy selector 代碼粘貼在(‘’)內 9 print(data)
運行腳本,可見上述元素已經獲取。
至此,已經獲得了一段目標元素的 HTML 代碼,但還沒有把數據提取出來。可以觀察所獲取的HTML代碼結構,對獲取的內容進行清洗。若獲取的HTML片段如行1所示,可以使用get_text()方法獲取字段”2.8mm“,若HTML片段如行2所示,可通過contents[0]方法獲取字段“05/21”。
1 [<div> 2.8mm </div>] data[0].get_text() 2 [<div class="date"> 05/21 <br/>周四 </div>] data[0].contents[0]
相對完整的代碼案例如下:
1 import requests # 加載 requests 庫,用於網頁獲取 2 from bs4 import BeautifulSoup # 加載 BeautifulSoup 庫,用於解析獲取的網頁 3 import csv # csv 庫(python 內置),用於讀寫csv文件 4 5 url = 'http://www.nmc.cn/publish/forecast/AGD/shunde.html' # 中央氣象台網順德區預報網頁 6 strHtml = requests.get(url) 7 strHtml.encoding = strHtml.apparent_encoding # 指定源網頁編碼方式作為文字解碼方式 8 soup = BeautifulSoup(strHtml.text, 'lxml') 9 Dict = {} 10 listDate = [] 11 for i in range(1, 8): 12 d_date = soup.select('#day7 > div:nth-child(' + str(i) + ') > div > div:nth-child(1)') # 日期 13 d_desc = soup.select('#day7 > div:nth-child(' + str(i) + ') > div > div:nth-child(3)') # 日間天氣 14 d_windd = soup.select('#day7 > div:nth-child(' + str(i) + ') > div > div:nth-child(4)') # 日間風向 15 d_winds = soup.select('#day7 > div:nth-child(' + str(i) + ') > div > div:nth-child(5)') # 日間風力 16 d_tmpH = soup.select('#day7 > div:nth-child(' + str(i) + ') > div > div:nth-child(6)') # 全天高溫 17 d_tmpL = soup.select('#day7 > div:nth-child(' + str(i) + ') > div > div:nth-child(7)') # 全天低溫 18 listDate.append(d_date[0].contents[0]) 19 arr = [listDate[i - 1], d_desc[0].get_text(), d_windd[0].get_text(), d_winds[0].get_text(), 20 d_tmpH[0].get_text(), d_tmpL[0].get_text()] 21 for j in range(len(arr)): 22 arr[j] = "".join(arr[j].split()) 23 Dict[listDate[i - 1]] = arr 24 print(d_desc[0].get_text() + " " + d_windd[0].get_text() + " " + d_winds[0].get_text() + " " + d_tmpH[ 25 0].get_text() + " " + d_tmpL[0].get_text()) 26 27 out = open('SD_Daily_Climate_Test.csv', 'a', newline='') # 設定寫入模式,參數'a'代表在其后追加內容 28 csv_write = csv.writer(out, dialect='excel') # 寫入具體內容 29 for item in Dict.values(): 30 csv_write.writerow(item) 31 print("write over SD Daily Climate Test")
輸出結果如下:
csv 保存內容如下:
參考資料