抓取貓眼電影top100
一、目標
運用requests+正則表示式爬取貓眼電影top100的電影圖片、名稱、時間、評分等資訊,提取站點的url為"http://maoyan.com/board/4",提取結果以文字的形式儲存下來。
二、準備工作
1. 安裝python
首先,下載Python3,這裡使用Python3.6.5版本,64位。
地址連結:https://www.python.org/downloads/
雙擊開啟,進行安裝。特別注意:要勾選上"Add to Path"選項,否則後面會很麻煩。
調出命令符視窗,輸入"python",如果出現下圖介面,就說明安裝成功。
2. 安裝pycharm
Pycharm是Python IDE的一種,可以幫助使用者提高效率,比如除錯、語法高亮、
從網站下載pycharm,下載連結為:
3. 安裝使用到的第三方庫:
requests庫:
request物件是從客戶端向伺服器發出請求,包括使用者提交的資訊以及客戶端的一些資訊。客戶端可通過HTML表單或在網頁地址後面提供引數的方法提交資料,然後通過request物件的相關方法來獲取這些資料。request的各種方法主要用來處理客戶端瀏覽器提交的請求中的各項引數和選項。
requests庫可以直接在pycharm下載(如下圖)
在開啟的setting介面中我們點選
在彈出的available packages介面中,你會看到一個搜尋框,如下圖所示
然後我們搜尋一個外掛,比如我搜索simplejson這個外掛,會出現如下圖所示的介面,點選下載
三、抓取分析
我們要抓取的目標站點為http://maoyan.com/board/4,開啟之後的磅單資訊如圖。
排名第一的電影是霸王別姬,頁面中顯示的有效資訊有影片名稱、主演、上映時間、上映地區、評分、圖片等資訊。
將頁面滾動到最下方,可以發現有分頁的列表,直接點選第二頁,可以發現頁面的URL變成http://maoyan.com/board/4?offset=10
可知offset代表偏移量,如果偏移量為n,則顯示電影序號就是n+1到n+10,每頁顯示10個,所以,如果想獲取TOP100電影,只需要分開請求10次,而10次的offset引數分別設定為0、10、20......90即可,這樣獲取不同的頁面之後,再用正則表示式提取出相關資訊,就可以得到TOP100的所有電影資訊了。
四、獲取首頁
1. 獲取一個url下的html檔案
def get_one_page(url):
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"}try: #異常處理respone = requests.get(url,headers=headers)if respone.status_code == 200:return respone.text #請求成功return None except RequestException:return Nonedef main(offset):#主函式執行url = "http://maoyan.com/board/4?offset="+str(offset) html = get_one_page(url)print(html)if __name__ == '__main__': main(1)
2. 抓取的結果如下(只擷取部分)
可以看到現在抓取的內容是很混亂的,我們很難找到有用的資訊,所以我們要用正則表示式進行網頁的解析。
五、正則提取
1. 用正則表示式解析網頁
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)print(items)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] }
2. 結果如下(只擷取部分結果)
六、寫入檔案
我們將爬取的結果寫入檔案,這裡直接寫入到一個文字檔案,這裡通過json庫的dumps()方法實現字典的序列化,並指定ensure_ascii的引數為Flase,這樣保證輸出結果是中文形式而是不Unicode編碼,程式碼如下:
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()
七、抓取一頁內容
我們進入到貓眼top100可以看到裡面有很多頁數,觀察他們的url,可以發現只是最後面不同而已,所以我們可以使用多執行緒抓取,提高抓取效率。
if __name__ == '__main__':
#for i in range(10): #抓取一頁# main(i*10)pool = Pool()#提高抓取效率pool.map(main,[i*10 for i in range(10)])
八、整合程式碼
1. 原始碼
import requestsimport reimport jsonfrom multiprocessing import Poolfrom requests.exceptions import RequestExceptiondef get_one_page(url):#獲取一個url下的html檔案headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"}try: #異常處理respone = requests.get(url,headers=headers)if respone.status_code == 200:return respone.text #請求成功return Noneexcept RequestException:return Nonedef 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)print(items)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] }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__':# for i in range(10): #抓取一頁 # main(i*10)pool = Pool()#提高抓取效率pool.map(main,[i*10 for i in range(10)])
2. 爬取結果