前言:這是學習Python的第三天,草草查閱了Python基礎語法以後想寫個demo練練手。找到一篇,效仿着寫了一遍,對於初學Python爬蟲的人來講是個很好的學習案例。如下是代碼解讀和關鍵點標註。html
使用語言:Python3.7python
開發工具:PyCharm正則表達式
引用地址:json
[http://www.javashuo.com/article/p-ovmsfcer-hr.html]:函數
# re庫,提供正則表達式支持 import re import json # requests庫,提供HTTP支持 import requests from requests import RequestException
注意: python畢竟是個腳本語言,從上到下執行,所以寫函數的時候須要注意前後順序,最早調用的寫在文件最上方,main函數通常在最下方,不然會報'XXX' is not defined喔!工具
# 經過url地址拿到網頁內容 def get_page(url): try: result = requests.get(url) if result.status_code == 200: return result.text return None except RequestException: return None
這裏寫法比較固定,你可能須要去了解的是HTTP各類狀態碼:學習
[https://baike.baidu.com/item/HTTP%E7%8A%B6%E6%80%81%E7%A0%81/5053660?fr=aladdin]:開發工具
# 正則表達式解析網頁數據,獲取想要的信息 def compile_html(html): pattern = re.compile('<li>.*?list_num.*?>(.*?).</div>.*?<img.*?src="(.*?)".*?class="name".*?title="(.*?)".*?class="tuijian">(.*?)</span>.*?</li>', re.S) items = re.findall(pattern, html) for item in items: yield { 'index': item[0], 'image': item[1], 'title': item[2], 'introducePercent': item[3] }
這裏你須要注意兩部分:ui
話說我在今天以前,對正則的理解真的→0,好在這裏的正則不難。「.*?」三個符號構成一個模糊替換單位,若是(.*?)使用括號括起來,表示括號內的內容就是你要獲取的內容。你只須要寫出.*?x(.*?)y.*?就能夠過濾出元素x與y之間的數據了,easy HA~?編碼
首先,re.compile(pattern, flags)的解釋:
pattern 指定編譯時的表達式字符串;
flags 編譯標誌位,用來聲明正則表達式的匹配方式。支持 re.L|re.M 同時匹配
因此,這裏pattern 不須要解釋,這裏的flags的聲明可查文檔,例:re.S 表明匹配包括換行在內的全部字符。
因此re.findall(pattern, html)還須要解釋?返回匹配成功的對象啊!
到此,這篇文章的核心代碼其實也就結束了。。。Yeah~ That’s it.
# 把數據保存在本地 def save_to_txt(item): with open("books.txt", "a+", encoding="utf-8") as file: file.write(json.dumps(item, ensure_ascii=False) + "\n") file.close()
這裏須要注意倆部分:
open的時候聲明一下編碼方式
json.dumps(item, ensure_ascii=False)
(1) json.dumps() 將字典轉化爲字符串;
(2) ensure_ascii=False:json.dumps 序列化時對中文默認使用ascii編碼,想輸出真正的中文須要指定ensure_ascii=False
# 主函數模塊 def main(pageIndex): # 根據不一樣頁數獲取對應頁面數據,噹噹網每條數據在20條 url = "http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-" + str(pageIndex) # 獲取url中的網頁內容 html = get_page(url) # 正則表達式獲取每條信息並打印,打印後存入本地文本文件 for item in compile_html(html): print(item) save_to_txt(item) if __name__ == '__main__': for i in range(1, 6): main(i)
嗯,總體代碼比較簡單,初學python很適合。Over~