1. 程式人生 > >教你用Python爬取豆瓣圖書Top250

教你用Python爬取豆瓣圖書Top250

質量、速度、廉價,選擇其中兩個

這篇文章將會用到上一篇文章所講的內容,如果沒有看過可以去看一下教你用Python寫excel

今天我們要做的就是用Python爬取豆瓣圖書Top250,先開啟網站看一下

今天不談這豆瓣圖書top250垃圾不垃圾的問題,只看看怎麼用python把資料爬取下來,首先先來看網頁結構,一個介面只有25本書,一共十個介面,點選切換可以發現介面的切換可以通過引數start控制

比如說https://book.douban.com/top250?start=0代表的就是第一頁,https://book.douban.com/top250?start=1代表的就是第二頁,像這樣的介面有10個

那我們要爬取哪些資訊呢,有書名 ,點選跳轉的超連結 ,作者、出版商、售價,評分,評論人數,介紹

開啟網址,chrome瀏覽器右鍵檢查或者F12,firefox可以右鍵檢視元素,瀏覽html結構

每一個table中就是一本書的資訊,我們只要按規則抽取就好了,現在準備一下步驟

  1. 迴圈10個網址
  2. 請求網址
  3. 抽取資料
  4. 儲存到xlsx裡

請求網址可以使用requests來做,直接 requests.get(target_url) 一步到位,主要問題在抽取資料上,在這方面,我們可以使用BeautifulSoup,Beautiful Soup是一個Python包,功能包括解析HTML、XML文件、修復含有未閉合標籤等錯誤的文件。這個擴充套件包為待解析的頁面建立一棵樹,以便提取其中的資料,這在網路資料採集時非常有用,該庫可以說是爬蟲利器啊

book = requests.get(target_url)
soup = BeautifulSoup(book.text, 'lxml')

我們使用lxml作為解析器,構建BeautifulSoup物件

table = soup.findAll('table', {"width": "100%"})

呼叫findAll,找到所有符合條件的節點,第一個引數是標籤名稱,第二個引數是要求,這裡是找到所有寬度為100%的table標籤,該方法返回的是一個列表

然後我們只需要按步驟取資料就好了,比如書名就是table.div.a.text

 網頁上有換行和空格,我們需要把這些不需要的東西去掉,可以使用replace方法替換掉

r_name = name.replace('\n', '').replace(' ', '')

如果你想取一個標籤的一個屬性可以通過鍵值對的形式取,比如資料鏈接

url = item.div.a['href']

要注意一點就是資訊並不總是完整的,有時可能空缺,如果你沒有做處理依舊去取這個值那麼程式便會報錯,比如這個書籍描述就不是所有書都有

最後儲存xlsx裡,上一篇文章說過,直接呼叫那個方法就可以了

附上一段完整程式

import re

import requests
from bs4 import BeautifulSoup
import xlsxwriter

def save_excel(fin_result, tag_name, file_name):
  book = xlsxwriter.Workbook(r'%s.xlsx' % file_name)
  tmp = book.add_worksheet()
  row_num = len(fin_result)
  for i in range(1, row_num+2):
    if i == 1:
      tag_pos = 'A%s' % i
      tmp.write_row(tag_pos, tag_name)
    else:
      con_pos = 'A%s' % i
      content = fin_result[i-2] # -2是因為當i=2時下標應為0
      tmp.write_row(con_pos, content)
  book.close()

def book(target_url):
    books = []
    book = requests.get(target_url)  # 使用requests返回網頁的整體結構
    soup = BeautifulSoup(book.text, 'lxml')  # 使用lxml作為解析器,返回一個Beautifulsoup物件
    table = soup.findAll('table', {"width": "100%"})  # 找到其中所有width=100%的table標籤),即找到所有的書
    for item in table:  # 遍歷table,一個item代表一本書
        name = item.div.a.text.strip()  # 找到書名
        r_name = name.replace('\n', '').replace(' ', '')  # 通過看網頁的HTML結構,可以發現書名後是有換行以及空格的,將這些全部通過replace替換去除
        url = item.div.a['href']  # 獲取書的連結
        info = item.find('p', {"class": "pl"}).text  # 獲取書的資訊
        score = item.find('span', {"class": "rating_nums"}).text.strip()  # 獲取分數
        nums = item.find('span', {"class": "pl"}).text.strip()  # 獲取評價人數
        num = re.findall('(\d+)人評價', nums)[0]  # 通過正則取具體的數字
        if item.find('span', {"class": "inq"}):  # 判斷是否存在描述
            desc = item.find('span', {"class": "inq"}).text.strip()
        else:
            desc = 'no description'
        books.append([r_name, url, info, score, num, desc])  # 以元組存入列表
    return books  # 返回一頁的書籍

result=[]
for n in range(10):
    url1 = 'https://book.douban.com/top250?start=' + str(n*25) #top250的網頁,每頁25本書,共10頁,“start=”後面從0開始,以25遞增
    result+= book(url1)
title_list=["書名","網址","作者/出版社/售價","評分","評論人數","介紹"]
print(result)
save_excel(result,title_list,"booktop250")