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

概述

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

涉及知識點

若是要實現爬蟲,須要掌握的Pyhton相關知識點以下所示:python

  • 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數據庫

爬取頁面截圖,以下所示:json

爬取數據步驟

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,而後便可正常訪問。app

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

 

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

備註

望嶽

唐·杜甫

岱宗夫如何?齊魯青未了。 造化鍾神秀,陰陽割昏曉。 蕩胸生曾雲,決眥入歸鳥。( 曾 同:層) 會當凌絕頂,一覽衆山小。 
相關文章
相關標籤/搜索