看到CSDN公衆號推薦的一個貓眼電影前100的爬蟲程序(來自於https://zhuanlan.zhihu.com/p/33819401),實現了下,記錄一下過程:
主要分爲3步:1. HTML下載器、2. HTML解析器、3. 數據存儲器。
需要的庫有requests,re(正則化表達式用),json(爬下來的數據格式是json格式,讀取處理用),multiprocessing(多進程)。requests知識可以看這個點擊打開鏈接,它是負責鏈接網站,處理http協議。
import requests
from requests.exceptions import RequestException
from multiprocessing import Pool
import re
import json
headers = {'User-Agent': 'Mozilla/5.0 '}
def get_one_page(url):
try:
res = requests.get(url, headers=headers)
if res.status_code == 200:
return res.text
return None
except RequestException:
return None
def parse_one_page(html):
pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
+'.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
+'.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',re.S)
items = re.findall(pattern,html)
for item in items:
yield{
'index': item[0],
'image': item[1],
'title': item[2],
'actor': item[3].strip()[3:],
'time': item[4].strip()[5:],
'score': item[5] + item[6]
} ##這裏yield在每次循環都能返回值item,如果用return則只會在for循環完了返回最後一個的值
def write_to_file(content):
with open ('result.txt', 'a',encoding='utf-8') as f:
f.write(json.dumps(content,ensure_ascii=False) + '\n')
f.close()
def main(offset):
url = 'http://maoyan.com/board/4?offset=' + str(offset)
html = get_one_page(url)
for item in parse_one_page(html):
print(item)
write_to_file(item)
if __name__ == '__main__':
p = Pool()
p.map(main,[i*10 for i in range(10)])
注意事項:1.爲什麼write_to_file函數裏面ensure_ascii=False?原因是json默認是以ASCII來解析code的,由於中文不在ASCII編碼當中,因此就不讓默認ASCII生效;open裏面‘a’是指在txt文件中追加寫,如果用‘w’則每次運行程序會覆蓋掉原來的。
2. if __name__ == '__main__'這個代碼的理解可以看這裏,意思大概就是說如果是直接運行這個程序,冒號後面的代碼會被運行,如果是import到別的程序裏面,冒號後面的代碼就不會被運行。(__name__ 是當前模塊名,當模塊被直接運行時模塊名爲 __main__ 。當模塊被直接運行時,代碼將被運行,當模塊是被導入時,代碼不被運行。)這裏實現的是運行程序是實現多線程,加快爬蟲速度。
服務器運行結果如下:
在控制檯打印出來是正常的(因爲程序在保存文件的時候已經設置爲encoding='utf-8'),vim出來也是好的,但是直接雙擊打開txt顯示是亂碼,將txt文件下載在自己電腦後打開也顯示正常,應該是服務器系統(ubantu(linux))的顯示編碼問題。