Requests+正则爬取猫眼电影TOP100
(一)目標站點的分析
首先打開我們的目標網站,發現每一頁有十個電影,最下面有分頁標志,而分頁只改變的是標簽后綴,如下:
而后可以在網頁按f12打開源代碼管理,查看網頁每處信息對應的源代碼形式,如下圖:
?
(二)流程框架
經過簡單分析后,我們可以整理一下總的流程分為四步:
?
?(三)實戰編碼
1.我們首先完成獲取一頁html信息的函數--抓取單頁內容:
1 import requests 2 from requests.exceptions import RequestException 3 4 5 def get_one_page(url, headers): 6 try: 7 response = requests.get(url, headers=headers) 8 if response.status_code == 403: 9 return '需要設置headers信息' 10 elif response.status_code == 200: 11 return response.text 12 else: 13 return None 14 except RequestException: 15 return 'Fault' 16 17 18 def main(): 19 url = 'http://maoyan.com/board/4?offset=0' 20 headers = { 21 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' 22 'Chrome/63.0.3239.132 Safari/537.36' 23 } 24 response = get_one_page(url, headers) 25 print(response) 26 27 28 if __name__ == '__main__': 29 main()注意,在這里我們會發現,如果不設置headers信息,我們會無法獲取html信息,所以需要設置一個headers信息才能打開網頁。
2.接下來,我們要對內容進行整理和抓取--正則分析:
1 import requests 2 from requests.exceptions import RequestException 3 import re 4 5 6 def get_one_page(url, headers): 7 try: 8 response = requests.get(url, headers=headers) 9 if response.status_code == 403: 10 return '需要設置headers信息' 11 elif response.status_code == 200: 12 return response.text 13 else: 14 return None 15 except RequestException: 16 return 'Fault' 17 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 items = re.findall(pattern, html) 24 #利用生成器實現格式化輸出: 25 for i in items: 26 yield { 27 'index': i[0], 28 'image': i[1], 29 'name': i[2], 30 'actor': i[3].strip()[3:], 31 'tmie': i[4].strip()[5:], 32 'score': i[5]+i[6] 33 } 34 35 36 def main(): 37 url = 'http://maoyan.com/board/4?offset=0' 38 headers = { 39 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' 40 'Chrome/63.0.3239.132 Safari/537.36' 41 } 42 html = get_one_page(url, headers) 43 #由于分析函數已經是一個迭代器了,所以可以迭代訪問: 44 for i in parse_one_page(html): 45 print(i) 46 47 48 if __name__ == '__main__': 49 main()這一步的重點就是第20-22的正則匹配,關鍵在于如何去定位我們所需要的信息,關于輸出這里用了生成器,其實不懂的話沒關系,可以直接輸出,這里只是為了方便觀看結果,下面是輸出結果:
1 {'index': '1', 'image': 'http://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c', 'name': '霸王別姬', 'actor': '張國榮,張豐毅,鞏俐', 'tmie': '1993-01-01', 'score': '9.6'} 2 {'index': '2', 'image': 'http://p0.meituan.net/movie/54617769d96807e4d81804284ffe2a27239007.jpg@160w_220h_1e_1c', 'name': '羅馬假日', 'actor': '格利高里·派克,奧黛麗·赫本,埃迪·艾伯特', 'tmie': '1953-09-02(美國)', 'score': '9.1'} 3 {'index': '3', 'image': 'http://p0.meituan.net/movie/283292171619cdfd5b240c8fd093f1eb255670.jpg@160w_220h_1e_1c', 'name': '肖申克的救贖', 'actor': '蒂姆·羅賓斯,摩根·弗里曼,鮑勃·岡頓', 'tmie': '1994-10-14(美國)', 'score': '9.5'} 4 {'index': '4', 'image': 'http://p0.meituan.net/movie/e55ec5d18ccc83ba7db68caae54f165f95924.jpg@160w_220h_1e_1c', 'name': '這個殺手不太冷', 'actor': '讓·雷諾,加里·奧德曼,娜塔莉·波特曼', 'tmie': '1994-09-14(法國)', 'score': '9.5'} 5 {'index': '5', 'image': 'http://p1.meituan.net/movie/f5a924f362f050881f2b8f82e852747c118515.jpg@160w_220h_1e_1c', 'name': '教父', 'actor': '馬龍·白蘭度,阿爾·帕西諾,詹姆斯·肯恩', 'tmie': '1972-03-24(美國)', 'score': '9.3'} 6 {'index': '6', 'image': 'http://p1.meituan.net/movie/0699ac97c82cf01638aa5023562d6134351277.jpg@160w_220h_1e_1c', 'name': '泰坦尼克號', 'actor': '萊昂納多·迪卡普里奧,凱特·溫絲萊特,比利·贊恩', 'tmie': '1998-04-03', 'score': '9.5'} 7 {'index': '7', 'image': 'http://p0.meituan.net/movie/da64660f82b98cdc1b8a3804e69609e041108.jpg@160w_220h_1e_1c', 'name': '唐伯虎點秋香', 'actor': '周星馳,鞏俐,鄭佩佩', 'tmie': '1993-07-01(中國香港)', 'score': '9.2'} 8 {'index': '8', 'image': 'http://p0.meituan.net/movie/b076ce63e9860ecf1ee9839badee5228329384.jpg@160w_220h_1e_1c', 'name': '千與千尋', 'actor': '柊瑠美,入野自由,夏木真理', 'tmie': '2001-07-20(日本)', 'score': '9.3'} 9 {'index': '9', 'image': 'http://p0.meituan.net/movie/46c29a8b8d8424bdda7715e6fd779c66235684.jpg@160w_220h_1e_1c', 'name': '魂斷藍橋', 'actor': '費雯·麗,羅伯特·泰勒,露塞爾·沃特森', 'tmie': '1940-05-17(美國)', 'score': '9.2'} 10 {'index': '10', 'image': 'http://p0.meituan.net/movie/230e71d398e0c54730d58dc4bb6e4cca51662.jpg@160w_220h_1e_1c', 'name': '亂世佳人', 'actor': '費雯·麗,克拉克·蓋博,奧利維婭·德哈維蘭', 'tmie': '1939-12-15(美國)', 'score': '9.1'} View Code
3.接下來就需要把信息保存至我們的文件--保存至文件:
1 import requests 2 from requests.exceptions import RequestException 3 import re 4 import json 5 6 def get_one_page(url, headers): 7 try: 8 response = requests.get(url, headers=headers) 9 if response.status_code == 403: 10 return '需要設置headers信息' 11 elif response.status_code == 200: 12 return response.text 13 else: 14 return None 15 except RequestException: 16 return 'Fault' 17 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 items = re.findall(pattern, html) 24 #利用生成器實現格式化輸出: 25 for i in items: 26 yield { 27 'index': i[0], 28 'image': i[1], 29 'name': i[2], 30 'actor': i[3].strip()[3:], 31 'tmie': i[4].strip()[5:], 32 'score': i[5]+i[6] 33 } 34 35 36 def write_to_file(content): 37 with open('result.txt', 'a', encoding='utf-8') as f: 38 f.write(json.dumps(content, ensure_ascii=False) + '\n') 39 f.close() 40 41 42 def main(): 43 url = 'http://maoyan.com/board/4?offset=0' 44 headers = { 45 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' 46 'Chrome/63.0.3239.132 Safari/537.36' 47 } 48 html = get_one_page(url, headers) 49 #由于分析函數已經是一個迭代器了,所以可以迭代訪問: 50 for i in parse_one_page(html): 51 write_to_file(i) 52 53 54 if __name__ == '__main__': 55 main()這里要注意37,38行的兩處轉碼操作,因為content是一個字典,我們需要將其轉成字符串,然后需要轉換成中文,因此有了如上兩步。
4.循環爬取所有頁數,采用往main中傳參數:
1 import requests 2 from requests.exceptions import RequestException 3 import re 4 import json 5 6 def get_one_page(url, headers): 7 try: 8 response = requests.get(url, headers=headers) 9 if response.status_code == 403: 10 return '需要設置headers信息' 11 elif response.status_code == 200: 12 return response.text 13 else: 14 return None 15 except RequestException: 16 return 'Fault' 17 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 items = re.findall(pattern, html) 24 #利用生成器實現格式化輸出: 25 for i in items: 26 yield { 27 'index': i[0], 28 'image': i[1], 29 'name': i[2], 30 'actor': i[3].strip()[3:], 31 'tmie': i[4].strip()[5:], 32 'score': i[5]+i[6] 33 } 34 35 36 def write_to_file(content): 37 with open('result.txt', 'a', encoding='utf-8') as f: 38 f.write(json.dumps(content, ensure_ascii=False) + '\n') 39 f.close() 40 41 42 def main(offset): 43 url = 'http://maoyan.com/board/4?offset=' + str(offset) 44 headers = { 45 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' 46 'Chrome/63.0.3239.132 Safari/537.36' 47 } 48 html = get_one_page(url, headers) 49 #由于分析函數已經是一個迭代器了,所以可以迭代訪問: 50 for i in parse_one_page(html): 51 write_to_file(i) 52 53 54 if __name__ == '__main__': 55 for i in range(10): 56 main(i*10) View Code
5.使用多線程進行抓取,提高效率:
主要就是引入一個進程池即可,這里了解一下其用法:
1 import requests 2 from requests.exceptions import RequestException 3 import re 4 import json 5 from multiprocessing import Pool 6 7 8 def get_one_page(url, headers): 9 try: 10 response = requests.get(url, headers=headers) 11 if response.status_code == 403: 12 return '需要設置headers信息' 13 elif response.status_code == 200: 14 return response.text 15 else: 16 return None 17 except RequestException: 18 return 'Fault' 19 20 21 def parse_one_page(html): 22 pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a' 23 '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>' 24 '.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', re.S) 25 items = re.findall(pattern, html) 26 #利用生成器實現格式化輸出: 27 for i in items: 28 yield { 29 'index': i[0], 30 'image': i[1], 31 'name': i[2], 32 'actor': i[3].strip()[3:], 33 'tmie': i[4].strip()[5:], 34 'score': i[5]+i[6] 35 } 36 37 38 def write_to_file(content): 39 with open('result.txt', 'a', encoding='utf-8') as f: 40 f.write(json.dumps(content, ensure_ascii=False) + '\n') 41 f.close() 42 43 44 def main(offset): 45 url = 'http://maoyan.com/board/4?offset=' + str(offset) 46 headers = { 47 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' 48 'Chrome/63.0.3239.132 Safari/537.36' 49 } 50 html = get_one_page(url, headers) 51 #由于分析函數已經是一個迭代器了,所以可以迭代訪問: 52 for i in parse_one_page(html): 53 write_to_file(i) 54 55 56 if __name__ == '__main__': 57 pool = Pool() 58 pool.map(main, [i*10 for i in range(10)])?
OK,到此,這個簡單的爬蟲就結束了。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/boru-computer/p/9736780.html
總結
以上是生活随笔為你收集整理的Requests+正则爬取猫眼电影TOP100的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: phpstorm主题
- 下一篇: 区块链100讲:ERC20 中文版