Python基礎之爬取豆瓣圖書信息


概述

所謂爬蟲,就是幫助我們從互聯網上獲取相關數據並提取有用的信息。在大數據時代,爬蟲是數據采集非常重要的一種手段,比人工進行查詢,采集數據更加方便,更加快捷。剛開始學爬蟲時,一般從靜態,結構比較規范的網頁入手,然后逐步深入。今天以爬取豆瓣最受關注圖書為例,簡述Python在爬蟲方面的初步應用,僅供學習分享使用,如有不足之處,還請指正。

涉及知識點

如果要實現爬蟲,需要掌握的Pyhton相關知識點如下所示:

  • requests模塊:requests是python實現的最簡單易用的HTTP庫,建議爬蟲使用requests。關於requests模塊的相關內容,可參考官方文檔及簡書上的說明
  • BeautifulSoup模塊:Beautiful Soup 是一個可以從HTML或XML文件中提取數據的Python庫。它能夠通過你喜歡的轉換器實現慣用的文檔導航,查找,修改文檔的方式。關於BeautifulSoup的更多內容,可參考官方文檔
  • json模塊:JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,易於人閱讀和編寫。使用 JSON 函數需要導入 json 庫。關於json的更多內容,可參考菜鳥筆記
  • re模塊:re模塊提供了與 Perl 語言類似的正則表達式匹配操作。關於re模塊的更多內容,可參考官方文檔

目標頁面

本例中爬取的信息為豆瓣最受關注圖書榜信息,共10本當前最受歡迎圖書。

爬取頁面URL【Uniform Resource Locator,統一資源定位器】:https://book.douban.com/chart?subcat=F

爬取頁面截圖,如下所示:

爬取數據步驟

1. 分析頁面

通過瀏覽器提供的開發人員工具(快捷鍵:F12),可以方便的對頁面元素進行定位,經過定位分析,本次所要獲取的內容,包括在UL【class=chart-dashed-list】標簽內容,每一本書,都對應一個LI元素,是本次爬取的目標,如下所示:

 

 每一本書,對應一個Li【class=media clearfix】元素,書名為對應a【class=fleft】元素,描述為P【class=subject-abstract color-gray】標簽元素內容,具體到每一本書的的詳細內容,如下所示:

 

2. 下載數據

如果要分析數據,首先要進行下載,獲取要爬取的數據信息,在Python中爬取數據,主要用requests模塊,如下所示:

 1 def get_data(url):
 2     """
 3     獲取數據
 4     :param url: 請求網址
 5     :return:返回請求的頁面內容
 6     """
 7     # 請求頭,模擬瀏覽器,否則請求會返回418
 8     header = {
 9         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
10                       'Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'}
11     resp = requests.get(url=url, headers=header)  # 發送請求
12     if resp.status_code == 200:
13         # 如果返回成功,則返回內容
14         return resp.text
15     else:
16         # 否則,打印錯誤狀態碼,並返回空
17         print('返回狀態碼:', resp.status_code)
18         return ''

注意:在剛開始寫爬蟲時,通常會遇到“HTTP Error 418”,請求網站的服務器端會進行檢測此次訪問是不是人為通過瀏覽器訪問,如果不是,則返回418錯誤碼。檢測請求頭是常見的反爬蟲策略,所為為了模擬瀏覽器訪問,需要構造請求Header,然后即可正常訪問。

正常瀏覽器訪問成功的狀態碼為200,及請求標頭中User-Agent。如下所示:

 

3. 解析數據

當獲取到數據后,需要進行數據分析,才能得到想要的內容。requests模塊獲取到的內容為Html源碼字符串,可以通過BeautifulSoup裝載成對象,然后進行數據獲取,如下所示:

 1 def parse_data(html: str = None):
 2     """
 3     解析數據
 4     :param html:
 5     :return:返回書籍信息列表
 6     """
 7     bs = BeautifulSoup(html, features='html.parser')  # 轉換頁面內容為BeautifulSoup對象
 8     ul = bs.find(name='ul', attrs={'class': 'chart-dashed-list'})  # 獲取列表的父級內容
 9     lis = ul.find_all('li', attrs={'class': re.compile('^media clearfix')})  # 獲取圖書列表
10     books = []  # 定義圖書列表
11     for li in lis:
12         # 循環遍歷列表
13         strong_num = li.find(name='strong', attrs={'class': 'fleft green-num-box'})  # 獲取書籍排名標簽
14         book_num = strong_num.text  # 編號
15         h2_a = li.find(name='a', attrs={'class': 'fleft'})  # 獲取書名標簽
16         book_name = h2_a.text  # 獲取書名
17         p_info = li.find(name='p', attrs={'class': "subject-abstract color-gray"})  # 書籍說明段落標簽
18 
19         book_info_str = p_info.text.strip()  # 獲取書籍說明,並 去前后空格
20         # book_info_list = book_info_str.split('/', -1) # 分隔符
21         books.append(
22             {'book_num': book_num, 'book_name': book_name, 'book_info': book_info_str})  # 將內容添加到列表
23 
24     return books

4. 保存數據

解析到目標數據后,需要進行數據持久化,以便后續進一步分析。持久化通常可以保存到數據庫中,本例為了簡單,保存到本地json文件中,如下所示:

1 def save_data(res_list):
2     """
3     保存數據
4     :param res_list: 保存的內容文件
5     :return:
6     """
7     with open('books.json', 'w', encoding='utf-8') as f:
8         res_list_json = json.dumps(res_list, ensure_ascii=False)
9         f.write(res_list_json)

本例完整代碼,如下所示:

 1 import json  # json 包,用於讀取解析,生成json格式的文件內容
 2 import requests  # 請求包  用於發起網絡請求
 3 from bs4 import BeautifulSoup  # 解析頁面內容幫助包
 4 import re  # 正則表達式
 5 
 6 
 7 def get_data(url):
 8     """
 9     獲取數據
10     :param url: 請求網址
11     :return:返回請求的頁面內容
12     """
13     # 請求頭,模擬瀏覽器,否則請求會返回418
14     header = {
15         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
16                       'Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'}
17     resp = requests.get(url=url, headers=header)  # 發送請求
18     if resp.status_code == 200:
19         # 如果返回成功,則返回內容
20         return resp.text
21     else:
22         # 否則,打印錯誤狀態碼,並返回空
23         print('返回狀態碼:', resp.status_code)
24         return ''
25 
26 
27 def parse_data(html: str = None):
28     """
29     解析數據
30     :param html:
31     :return:返回書籍信息列表
32     """
33     bs = BeautifulSoup(html, features='html.parser')  # 轉換頁面內容為BeautifulSoup對象
34     ul = bs.find(name='ul', attrs={'class': 'chart-dashed-list'})  # 獲取列表的父級內容
35     lis = ul.find_all('li', attrs={'class': re.compile('^media clearfix')})  # 獲取圖書列表
36     books = []  # 定義圖書列表
37     for li in lis:
38         # 循環遍歷列表
39         strong_num = li.find(name='strong', attrs={'class': 'fleft green-num-box'})  # 獲取書籍排名標簽
40         book_num = strong_num.text  # 編號
41         h2_a = li.find(name='a', attrs={'class': 'fleft'})  # 獲取書名標簽
42         book_name = h2_a.text  # 獲取書名
43         p_info = li.find(name='p', attrs={'class': "subject-abstract color-gray"})  # 書籍說明段落標簽
44 
45         book_info_str = p_info.text.strip()  # 獲取書籍說明,並 去前后空格
46         # book_info_list = book_info_str.split('/', -1) # 分隔符
47         books.append(
48             {'book_num': book_num, 'book_name': book_name, 'book_info': book_info_str})  # 將內容添加到列表
49 
50     return books
51 
52 
53 def save_data(res_list):
54     """
55     保存數據
56     :param res_list: 保存的內容文件
57     :return:
58     """
59     with open('books.json', 'w', encoding='utf-8') as f:
60         res_list_json = json.dumps(res_list, ensure_ascii=False)
61         f.write(res_list_json)
62 
63 
64 #  開始執行,調用函數
65 url = 'https://book.douban.com/chart?subcat=F'
66 html = get_data(url=url)  # 獲取數據
67 books = parse_data(html)  # 解析數據
68 save_data(books)  # 保存數據
69 print('done')
View Code

本例爬取內容,保存到books.json文件中,如下所示:

 1 [
 2   {
 3     "book_num": "1",
 4     "book_name": "心靈偵探城塚翡翠",
 5     "book_info": "相澤沙呼 / 2021-4 / 人民文學出版社 / 79.00元 / 精裝"
 6   },
 7   {
 8     "book_num": "2",
 9     "book_name": "平原上的摩西",
10     "book_info": "雙雪濤 / 2021-4 / 北京日報出版社 / 59 / 精裝"
11   },
12   {
13     "book_num": "3",
14     "book_name": "眩暈",
15     "book_info": "[德國] 溫弗里德·塞巴爾德 / 2021-4 / 廣西師范大學出版社 / 52.00元 / 精裝"
16   },
17   {
18     "book_num": "4",
19     "book_name": "一把刀,千個字",
20     "book_info": "王安憶 / 2021-4 / 人民文學出版社 / 精裝"
21   },
22   {
23     "book_num": "5",
24     "book_name": "字母表謎案",
25     "book_info": "大山誠一郎 / 2021-5 / 河南文藝出版社 / 42.00 / 平裝"
26   },
27   {
28     "book_num": "6",
29     "book_name": "星之繼承者",
30     "book_info": "[英] 詹姆斯·P.霍根 / 2021-4 / 新星出版社 / 58.00元 / 精裝"
31   },
32   {
33     "book_num": "7",
34     "book_name": "美麗黑暗",
35     "book_info": "[法] 法比安·韋爾曼  編 / [法] 凱拉斯科多  繪 / 2021-4 / 后浪丨中國紡織出版社 / 88.00元 / 精裝"
36   },
37   {
38     "book_num": "8",
39     "book_name": "",
40     "book_info": "[日] 夏目漱石 / 2021-3-30 / 江蘇鳳凰文藝出版社 / 45.00元 / 精裝"
41   },
42   {
43     "book_num": "9",
44     "book_name": "奇跡唱片行",
45     "book_info": "[英] 蕾秋·喬伊斯 / 2021-6-11 / 北京聯合出版公司 / 48 / 平裝"
46   },
47   {
48     "book_num": "10",
49     "book_name": "派對恐懼症",
50     "book_info": "[美]卡門•瑪麗亞•馬查多 / 2021-5 / 世紀文景/上海人民出版社 / 59.00元 / 精裝"
51   }
52 ]
View Code

備注

望岳

唐·杜甫

岱宗夫如何?齊魯青未了。
造化鍾神秀,陰陽割昏曉。
盪胸生曾雲,決眥入歸鳥。( 曾 同:層)
會當凌絕頂,一覽眾山小。 


免責聲明!

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



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