Python爬蟲-爬取豆瓣圖書Top250

豆瓣網站很人性化,對於新手爬蟲比較友好,沒有若是調低爬取頻率,不用擔憂會被封 IP。但也不要太頻繁爬取。html

涉及知識點:requests、html、xpath、csv瀏覽器

1、準備工做函數

須要安裝requests、lxml、csv庫優化

爬取目標:https://book.douban.com/top250網站

2、分析頁面源碼url

打開網址,按下F12,而後查找書名,右鍵彈出菜單欄 Copy==> Copy Xpathspa

 

以書名「追風箏的人」 獲取書名的xpath是://*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[2]/div[1]/a3d

這裏須要注意一下,瀏覽器複製的xpath只能做參考,由於瀏覽器常常會在本身裏面增長多餘的tbody標籤,咱們須要手動把這個標籤刪除,整理成//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[1]/acode

一樣獲取圖書的評分、評論人數、簡介,結果以下:orm

//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[2]/span[2]

//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[2]/span[3]

//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/p[1]

初步代碼

import requests
from lxml import etree

html = requests.get('https://book.douban.com/top250').text
res = etree.HTML(html)
#由於要獲取標題文本,因此xpath表達式要追加/text(),res.xpath返回的是一個列表,且列表中只有一個元素因此追加一個[0]
name = res.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a/text()')[0].strip()
score = res.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[2]/span[2]/text()')[0].strip()
comment = res.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[2]/span[3]/text()')[0].strip()
info = res.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/p[1]/text()')[0].strip()
print(name,score,comment,info)

執行顯示:

這裏只是獲取第一條圖書的信息,獲取第2、第三看看

 

獲得xpath:

import requests
from lxml import etree

html = requests.get('https://book.douban.com/top250').text
res = etree.HTML(html)
name1 = res.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a/text()')[0].strip()
name2 = res.xpath('//*[@id="content"]/div/div[1]/div/table[2]/tr/td[2]/div[1]/a/text()')[0].strip()
name3 = res.xpath('//*[@id="content"]/div/div[1]/div/table[3]/tr/td[2]/div[1]/a/text()')[0].strip()
print(name1,name2,name3)

執行顯示:

對比他們的xpath,發現只有table序號不同,咱們能夠就去掉序號,獲得所有關於書名的xpath信息:

import requests
from lxml import etree

html = requests.get('https://book.douban.com/top250').text
res = etree.HTML(html)
names = res.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]/div[1]/a/text()')
for name in names:
    print(name.strip())

執行結果:太多,這裏只展現一部分

對於其餘評分、評論人數、簡介也一樣使用此方法來獲取。

到此,根據分析到的信息進行規律對比,寫出獲取第一頁圖書信息的代碼:

import requests
from lxml import etree

html = requests.get('https://book.douban.com/top250').text
res = etree.HTML(html)
trs = res.xpath('//*[@id="content"]/div/div[1]/div/table/tr')
for tr in trs:
    name = tr.xpath('./td[2]/div[1]/a/text()')[0].strip()
    score = tr.xpath('./td[2]/div[2]/span[2]/text()')[0].strip()
    comment = tr.xpath('./td[2]/div[2]/span[3]/text()')[0].strip()
    info = tr.xpath('./td[2]/p[1]/text()')[0].strip()
    print(name,score,comment,info)

執行結果展現(內容較多,只展現前部分)

以上只是獲取第一頁的數據,接下來,咱們獲取到所有頁數的連接,而後進行循環便可

3、獲取所有連接地址

查看分析頁數對應網頁源碼:

以代碼實現

for i in range(10):
    url = 'https://book.douban.com/top250?start={}'.format(i * 25)
    print(url)

執行結果:正是正確的結果

通過分析,已經獲取到所有的頁面連接和每一頁的數據提取,最後把總體代碼進行整理和優化。

完整代碼

#-*- coding:utf-8 -*-
"""
-------------------------------------------------
   File Name:     DoubanBookTop250
   Author :        zww
   Date:          2019/5/13
   Change Activity:2019/5/13
-------------------------------------------------
"""
import requests
from lxml import etree

#獲取每頁地址
def getUrl():
    for i in range(10):
        url = 'https://book.douban.com/top250?start={}'.format(i*25)
        urlData(url)
#獲取每頁數據
def urlData(url):
    html = requests.get(url).text
    res = etree.HTML(html)
    trs = res.xpath('//*[@id="content"]/div/div[1]/div/table/tr')
    for tr in trs:
        name = tr.xpath('./td[2]/div/a/text()')[0].strip()
        score = tr.xpath('./td[2]/div/span[2]/text()')[0].strip()
        comment = tr.xpath('./td[2]/div/span[3]/text()')[0].replace('(','').replace(')','').strip()
        info = tr.xpath('./td[2]/p[1]/text()')[0].strip()
        print("《{}》--{}分--{}--{}".format(name,score,comment,info))

if __name__ == '__main__':
    getUrl()

執行結果:總共250條圖書信息,一條很多,因爲數據太多,只展現前部分

 把爬取到的數據存儲到csv文件中

def write_to_file(content):
    #‘a’追加模式,‘utf_8_sig’格式處處csv不亂碼
    with open('DoubanBookTop250.csv','a',encoding='utf_8_sig',newline='') as f:
        fieldnames = ['name','score','comment','info']
        #利用csv包的DictWriter函數將字典格式數據存儲到csv文件中
        w = csv.DictWriter(f,fieldnames=fieldnames)
        w.writerow(content)

完整代碼

#-*- coding:utf-8 -*-
"""
-------------------------------------------------
   File Name:     DoubanBookTop250
   Author :        zww
   Date:          2019/5/13
   Change Activity:2019/5/13
-------------------------------------------------
"""
import csv
import requests
from lxml import etree

#獲取每頁地址
def getUrl():
    for i in range(10):
        url = 'https://book.douban.com/top250?start={}'.format(i*25)
        for item in urlData(url):
            write_to_file(item)
        print('成功保存豆瓣圖書Top250第{}頁的數據!'.format(i+1))

#數據存儲到csv
def write_to_file(content):
    #‘a’追加模式,‘utf_8_sig’格式處處csv不亂碼
    with open('DoubanBookTop250.csv','a',encoding='utf_8_sig',newline='') as f:
        fieldnames = ['name','score','comment','info']
        #利用csv包的DictWriter函數將字典格式數據存儲到csv文件中
        w = csv.DictWriter(f,fieldnames=fieldnames)
        w.writerow(content)

#獲取每頁數據
def urlData(url):
    html = requests.get(url).text
    res = etree.HTML(html)
    trs = res.xpath('//*[@id="content"]/div/div[1]/div/table/tr')
    for tr in trs:
        yield {
        'name':tr.xpath('./td[2]/div/a/text()')[0].strip(),
        'score':tr.xpath('./td[2]/div/span[2]/text()')[0].strip(),
        'comment':tr.xpath('./td[2]/div/span[3]/text()')[0].replace('(','').replace(')','').strip(),
        'info':tr.xpath('./td[2]/p[1]/text()')[0].strip()
        }
        #print("《{}》--{}分--{}--{}".format(name,score,comment,info))

if __name__ == '__main__':
    getUrl()

內容過多,只展現前部分

相關文章
相關標籤/搜索