Web爬蟲|入門實戰之貓眼電影


版權聲明:原創不易,本文禁止抄襲、轉載,侵權必究!

一、爬蟲任務

任務背景:爬取貓眼電影Top100數據

任務目標:運用正則表達式去解析網頁源碼並獲得所需數據

 


 

二、解析

任務URLhttps://maoyan.com/board/4?offset=0

 

下圖為貓眼電影的第一頁:

 

再看看第二頁:

 

最后看看第三頁:

 

我們把這三頁的URL復制下來,看一下URL規律:

1 https://maoyan.com/board/4?offset=0
2 https://maoyan.com/board/4?offset=10
3 https://maoyan.com/board/4?offset=20

從上面的URL可以看出,只有offset變化,offset意為偏移量,從中可以看出每一頁的偏移量為10,可以把該參數定義為自變量,然后用循環爬取前10頁的數據,也就是top100的數據

 

爬取任務

爬取貓眼電影top100電影的電影排名,圖片地址,演員,電影名,上映時間以及電影評分

 

解析網頁源代碼

 

點擊箭頭打開dd標簽塊,看看具體的信息:

 

再看看network中的真實數據:

從以上的圖中可以看出貓眼電影的數據都保存在dd標簽塊中,接下來就要用正則表達式去匹配所需的數據,再把這些數據以json格式保存到文本文件中以及MongoDB數據庫中

 


 

 三、編碼

獲取網頁源碼

定義一個去獲取HTML源碼的方法

 1 import requests
 2 from requests import exceptions
 3 
 4 def get_one_page(url):
 5   '''
 6   headers表示要傳遞的頭信息,'User-Agent'表示偽裝瀏覽器
 7   '''
 8   try:
 9     headers = {'User-Agent':'Mozilla/5.0'}
10     response = requests.get(url,headers=headers)
11     if response.status_code == 200:
12       return response.text
13     else:
14       return None
15  except exceptions.RequestException:
16     return None

 

解析源碼並獲得數據

 1 import re
 2 
 3 def parse_one_page(html):
 4   '''
 5   re.compile()方法會將正則表達式字符串轉換為正則表達式對象,方便以后的復用
 6   re.S表示修飾符,可以忽略換行符
 7   re.findall()方法會將所有符合匹配模式的數據返回,並且以列表形式返回 
 8   yield是Python中的關鍵字,表示生成器,類似於return
 9   strip()方法可以把空的部分去掉,包括空格,換行符等,但它的操作對象必須是字符串
10   '''
11   pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
12                          + '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
13                          + '.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',re.S)
14   movies_information = re.findall(pattern,html)
15   for movie_information in movies_information:
16     yield {
17       '電影排名':movie_information[0],
18       '圖片地址':movie_information[1],
19       '電影名':movie_information[2].strip(),
20       '演員':movie_information[3].strip()[3:] if len(movie_information) > 3 else '',
21       '上映時間':movie_information[4].strip()[5:] if len(movie_information) > 5 else '',
22       '評分':movie_information[5].strip() + movie_information[6].strip()
23     }

 

保存數據到文本文件

 1 import json
 2 
 3 def write_movies_data_to_file(movie_information):
 4   '''
 5   'a'表示以追加方式把數據寫入文件中,這樣就不會覆蓋之前寫入的數據
 6   json.dumps()方法可將json文本字符串序列化為json對象
 7   ensure_ascii=False表示忽略ASCII碼,默認也為False
 8   indent表示json格式的縮進
 9   '''
10   with open('../txt_file/maoyan_movies_information.txt','a',encoding='utf-8') as f:
11     f.write(json.dumps(movie_information,indent=2,ensure_ascii=False) + '\n')

 

保存數據到MongoDB數據庫

 1 import pymongo
 2 
 3 def insert_to_mongodb(content):
 4   '''
 5   client表示操作MongoDB數據庫的對象
 6   db表示數據庫對象
 7   collection表示集合對象,類似於MySQL中的table
 8   '''
 9   client = pymongo.MongoClient(host='localhost',port=27017)
10   db = client['spiders']
11   collection = db['maoyan_movies_data']
12   try:
13     if content:
14       collection.insert(content)
15       print('Success to insert!')
16   except:
17     print('Failed to insert!')

 

定義main()方法控制程序的運行

 1 def main(offset):
 2   '''
 3   offset={offset}表示頁數偏移量,這里用f-string函數把它設置為自變量,從而可以循環爬取
 4   '''
 5   url = f'https://maoyan.com/board/4?offset={offset}'
 6   html = get_one_page(url)
 7   for movie_information in parse_one_page(html):
 8     print(movie_information)
 9     write_movies_data_to_file(movie_information)
10     insert_to_mongodb(movie_information)

 

主程序運行

1 import time
2 
3 if __name__ == '__main__':
4   '''
5   time模塊延遲爬取時間,貓眼已經加了反爬
6   '''
7   for i in range(10):
8     main(offset=i*10)
9     time.sleep(1)

 

完整源碼如下

 1 import requests
 2 import re
 3 import time
 4 from requests import exceptions
 5 import json
 6 import pymongo
 7 
 8 def get_one_page(url):
 9   try:
10     headers = {'User-Agent':'Mozilla/5.0'}
11     response = requests.get(url,headers=headers)
12     if response.status_code == 200:
13       return response.text
14     else:
15       return None
16   except exceptions.RequestException:
17     return None
18 
19 def parse_one_page(html):
20   pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
21                          + '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
22                          + '.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',re.S)
23   movies_information = re.findall(pattern,html)
24   for movie_information in movies_information:
25     yield {
26       '電影排名':movie_information[0],
27       '圖片地址':movie_information[1],
28       '電影名':movie_information[2].strip(),
29       '演員':movie_information[3].strip()[3:] if len(movie_information) > 3 else '',
30       '上映時間':movie_information[4].strip()[5:] if len(movie_information) > 5 else '',
31       '評分':movie_information[5].strip() + movie_information[6].strip()
32     }
33 
34 def write_movies_data_to_file(movie_information):
35   with open('../txt_file/maoyan_movies_information.txt','a',encoding='utf-8') as f:
36     f.write(json.dumps(movie_information,indent=2,ensure_ascii=False) + '\n')
37 
38 def main(offset):
39   url = f'https://maoyan.com/board/4?offset={offset}'
40   html = get_one_page(url)
41   for movie_information in parse_one_page(html):
42     print(movie_information)
43     write_movies_data_to_file(movie_information)
44     insert_to_mongodb(movie_information)
45 
46 def insert_to_mongodb(content):
47   client = pymongo.MongoClient(host='localhost',port=27017)
48   db = client['spiders']
49   collection = db['maoyan_movies_data']
50   try:
51     if content:
52       collection.insert(content)
53       print('Success to insert!')
54   except:
55     print('Failed to insert!')
56 
57 if __name__ == '__main__':
58   for i in range(10):
59     main(offset=i*10)
60     time.sleep(1)

 

運行效果

控制台輸出:

 

json格式的txt文本結果:

 

 

MongoDB輸出結果:

 

 


 

四、總結

請求庫requests及exceptions模塊

標准庫re

time模塊

json模塊

Python與MongoDB數據庫對接的pymongo庫

 

 原創不易,如果覺得有點用,希望可以隨手點個贊,拜謝各位老鐵!

 


 

 

五、作者Info

作者:南柯樹下,Goal:讓編程更有趣!

原創微信公眾號:『小鴻星空科技』,專注於算法、爬蟲,網站,游戲開發,數據分析、自然語言處理,AI等,期待你的關注,讓我們一起成長、一起Coding!

轉載說明:本文禁止抄襲、轉載 ,侵權必究!

 


 更多獨家精彩內容  掃碼關注個人公眾號我們一起成長,一起Coding,讓編程更有趣!


 

——  ——  ——  ——  —  END  ——  ——  ——  ——  ———— 

         歡迎掃碼關注我的公眾號

          小鴻星空科技

       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM