14-Requests+正則表達式爬取貓眼電影
阿新 • • 發佈:2018-11-29
ons 亂碼 aci resp 正則 app 名稱 header ascii
‘‘‘Requests+正則表達式爬取貓眼電影TOP100‘‘‘
‘‘‘
流程框架:
抓去單頁內容:利用requests請求目標站點,得到單個網頁HTML代碼,返回結果。
正則表達式分析:根據HTML代碼分析得到電影的名稱、主演、上映時間、評分、圖片鏈接等信息。
保存至文件:通過文件的形式保存結果,每一部電影一個結果一行Json字符串。
開啟循環及多線程:對多頁內容遍歷,開啟多線程提高抓取速度。
‘‘‘
import requests
import re
from requests.exceptions import RequestException
import json
from multiprocessing import Pool
def get_one_page(url,headers):
‘‘‘得到網頁源碼‘‘‘
try:
#此處必須要傳入headers參數,否則因為有些網站服務器的反爬機制,會返回403 Forbidden。參考:https://blog.csdn.net/lv0817/article/details/79185322
response = requests.get(url=url,headers=headers) #這裏要註意,必須使用url=url,headers=headers的格式,否則傳參無效。
if response.status_code == 200:
return response.text
return None
#可以查看requests庫的官方文檔的Exceptions模塊,可知RequestException為所有異常的父類或間接父類。
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][5:],
‘score‘:item[5]+item[6]
}
def write_to_file(content):
‘‘‘解析好的數據寫入到文件‘‘‘
with open(‘result.txt‘,‘a‘,encoding=‘utf-8‘) as f: #‘a‘表示內容可追加。當有中文時,指定編碼utf-8防止亂碼。
#json.dumps序列化時對中文默認使用的ascii編碼.想輸出真正的中文需要指定ensure_ascii = False。
f.write(json.dumps(content,ensure_ascii=False) + ‘\n‘) #json.dumps將字典轉換為字符串
f.close()
def main(offset):
url = "http://maoyan.com/board/4?offset=" + str(offset) #點擊下一頁觀察網址可知
headers = {
‘User-Agent‘: ‘Mozilla/5.0(Macintosh;Intel Mac OS X 10_11_4)AppleWebKit/537.36(KHTML,like Gecko)Chrome/52.0.2743.116 Safari/537.36‘
}
html = get_one_page(url,headers)
#遍歷生成器
for item in parse_one_page(html):
print(item)
write_to_file(item)
if __name__ == ‘__main__‘:
# for i in range(10):
# main(i*10)
#如果要實現秒抓的話,就要使用多進程。
#進程池提供指定數量的進程供用戶調用,如果有新的請求提交到進程池,池子還沒有滿,它就會創建新的進程來執行請求,如果池子滿了就先等待。
#構造進程池
pool = Pool() #聲明一個進程池
pool.map(main,[i*10 for i in range(10)]) #第一個參數是方法名,第二個參數是可遍歷對象。map方法作用是,拿出可遍歷數組中的每一個值當做函數的參數,然後創建一個個的進程,放到進程池裏面去運行。
14-Requests+正則表達式爬取貓眼電影