#1 爬蟲:豆瓣圖書TOP250 「requests、BeautifulSoup」


一、項目背景

隨着時代的發展,國人對於閱讀的需求也是日益增長,既然要閱讀,就要讀好書,什么是好書呢?本項目選擇以豆瓣圖書網站為對象,統計其排行榜的前250本書籍。

二、項目介紹

本項目使用Python爬蟲技術統計豆瓣圖書網站上排名前250的書籍信息,包括書名、作者、出版社、出版日期、價格、評星、簡述信息

將獲取到的信息存儲在Mysql數據庫中

三、項目流程

3.1 分析第一頁

第一頁地址為:https://book.douban.com/top250,打開后頁面呈現為如下: 

 我們需要獲得的信息為每一本書的所有信息: 

所以思路為:

解析這一頁--->得到這一頁所有圖書的信息

3.2 解析第一頁

使用開發者模式查看網頁源代碼(Chrome瀏覽器按F12),選擇network后,刷新網頁,效果如下圖: 

 之后點擊top250--->Response,如下圖:

此時就會在右下方看到網頁的源代碼,分析源代碼可知:

每一本書都是被「table標簽,class=item」擴起來的,比如《追風箏的人》源代碼在253-307行。

使用requests模塊獲取源代碼,Python代碼如下:

import requests

def
parse_index(url): ''' 解析索引頁面 返回圖書所有信息 ''' try: response = requests.get(url) if response.status_code == 200: return response.text except Exception as e: print('error:', e)

『防抄襲:讀者請忽略這段文字,文章作者是博客園的MinuteSheep

3.3 解析圖書詳細信息

獲取到頁面源代碼后,接下來要做的工作就是解析每一本圖書的詳細信息了。所以思路繼續深入:

解析這一頁--->得到這一頁所有圖書的信息--->解析一本圖書--->將圖書詳細信息保存為字典格式

書名都是被「a標簽」擴起來的,比如《追風箏的人》書名源代碼在268-274行;

作者、出版社、出版日期、價格都是被「p標簽,class=pl」擴起來的,比如《追風箏的人》這些信息源代碼在285行;

評星都是被「span標簽,class=rating_nums」擴起來的,比如《追風箏的人》評星源代碼在292行;

簡述信息都是被「span標簽,class=inq」擴起來的,比如《追風箏的人》簡述信息源代碼在301行。

Python源代碼如下:

from bs4 import BeautifulSoup

def
parse(text): ''' 解析圖書詳細信息 ''' soup = BeautifulSoup(text.strip(), 'lxml') books = soup.select('.item') info = {} for book in books: info.clear() info['title'] = book.select('.pl2 a')[0].get_text( ).strip().replace(' ', '').replace('\n', '') info['author'] = book.select( '.pl')[0].get_text().strip().split('/')[0].strip() info['publishers'] = book.select( '.pl')[0].get_text().strip().split('/')[-3].strip() info['date'] = book.select( '.pl')[0].get_text().strip().split('/')[-2].strip() info['price'] = book.select( '.pl')[0].get_text().strip().split('/')[-1].strip() info['star'] = float(book.select('.rating_nums')[0].get_text()) info['summary'] = book.select('.inq')[0].get_text( ).strip() if book.select('.inq') else '' yield info

3.4 將信息保存在Mysql數據庫

進入Mysql的交互環境,依次建立數據庫、創建數據表:

create database douban;
use douban;
create table book_top250(
-> id int not null primary key auto_increment,
-> title char(100) not null unique key,
-> author char(100) not null,
-> publisher char(100),
-> date char(100),
-> price char(100)
-> star float,
-> summary char(100)
->);

之后使用Mysql官方推薦的連接庫:mysql.connector

Python代碼如下:

import mysql.connector

def
open_mysql(): ''' 連接mysql ''' cnx = mysql.connector.connect(user='minutesheep', database='douban') cursor = cnx.cursor() return cnx, cursor def save_to_mysql(cnx, cursor, info): ''' 將數據寫入mysql ''' add_book_top250 = ("INSERT IGNORE INTO book_top250 " "(title,author,publishers,date,price,star,summary) " "VALUES (%(title)s, %(author)s, %(publishers)s, %(date)s, %(price)s, %(star)s, %(summary)s)") cursor.execute(add_book_top250, info) cnx.commit() def close_mysql(cnx, cursor): ''' 關閉mysql ''' cursor.close() cnx.close()

到此為止,一本圖書的信息就已經保存完畢了

3.5 遍歷本頁面所有圖書

現在只需要將本頁面的所有圖書遍歷一遍,就完成了一個頁面的抓取

『防抄襲:讀者請忽略這段文字,文章作者是博客園的MinuteSheep

3.6 遍歷所有頁面

最后只需要將所有頁面遍歷就可以抓取到250本圖書了。現在觀察每一頁的URL變化:

第一頁:https://book.douban.com/top250 或 https://book.douban.com/top250?start=0

第二頁:https://book.douban.com/top250?start=25

第三頁:https://book.douban.com/top250?start=50

第十頁(最后一頁):https://book.douban.com/top250?start=225

通過觀察可知,后一頁的URL只需要將前一頁的URL最后的數字加25

基於此,Python代碼為:

def main():
    base_url = 'https://book.douban.com/top250?start='
    cnx, cursor = open_mysql()
    for page in range(0, 250, 25):
        index_url = base_url + str(page)
        text = parse_index(index_url)
        info = parse(text)
        for result in info:
            save_to_mysql(cnx, cursor, result)
    close_mysql(cnx, cursor)

四、項目流程圖 

五、項目源代碼

import requests
from bs4 import BeautifulSoup
import mysql.connector


def parse_index(url):
    '''
    解析索引頁面
    返回圖書所有信息
    '''
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.text
    except Exception as e:
        print('error:', e)


def parse(text):
    '''
    解析圖書詳細信息
    '''
    soup = BeautifulSoup(text.strip(), 'lxml')
    books = soup.select('.item')
    info = {}
    for book in books:
        info.clear()
        info['title'] = book.select('.pl2 a')[0].get_text(
        ).strip().replace(' ', '').replace('\n', '')
        info['author'] = book.select(
            '.pl')[0].get_text().strip().split('/')[0].strip()
        info['publishers'] = book.select(
            '.pl')[0].get_text().strip().split('/')[-3].strip()
        info['date'] = book.select(
            '.pl')[0].get_text().strip().split('/')[-2].strip()
        info['price'] = book.select(
            '.pl')[0].get_text().strip().split('/')[-1].strip()
        info['star'] = float(book.select('.rating_nums')[0].get_text())
        info['summary'] = book.select('.inq')[0].get_text(
        ).strip() if book.select('.inq') else ''
        yield info


def open_mysql():
    '''
    連接mysql
    '''
    cnx = mysql.connector.connect(user='minutesheep', database='douban')
    cursor = cnx.cursor()
    return cnx, cursor


def save_to_mysql(cnx, cursor, info):
    '''
    將數據寫入mysql
    '''
    add_book_top250 = ("INSERT IGNORE INTO book_top250 "
                       "(title,author,publishers,date,price,star,summary) "
                       "VALUES (%(title)s, %(author)s, %(publishers)s, %(date)s, %(price)s, %(star)s, %(summary)s)")

    cursor.execute(add_book_top250, info)
    cnx.commit()


def close_mysql(cnx, cursor):
    '''
    關閉mysql
    '''
    cursor.close()
    cnx.close()


def main():
    base_url = 'https://book.douban.com/top250?start='
    cnx, cursor = open_mysql()
    for page in range(0, 250, 25):
        index_url = base_url + str(page)
        text = parse_index(index_url)
        info = parse(text)
        for result in info:
            save_to_mysql(cnx, cursor, result)
    close_mysql(cnx, cursor)


if __name__ == '__main__':
    main()
源代碼

整個項目地址:https://github.com/MinuteSheep/DoubanBookTop250

六、項目結果展示 

Mysql部分數據如下圖:

提醒:僅供學習使用,商用后果自負 


免責聲明!

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



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