pyquery爬取豆瓣讀書(shū)

本任務(wù)需求:

爬取豆瓣閱讀所有書(shū)籍的書(shū)名赵誓、出版社温圆、評(píng)分、簡(jiǎn)介等相關(guān)信息取逾。
豆瓣的網(wǎng)頁(yè)比較干凈整潔蜓竹,鏈接很有規(guī)律

本文具體邏輯順序:

先獲取書(shū)籍類(lèi)目及網(wǎng)址
獲取每個(gè)類(lèi)目所有頁(yè)面的鏈接
獲取書(shū)籍名箕母、出版社、評(píng)分等信息
銜接前面4部分的代碼俱济。

一嘶是、獲取豆瓣閱讀所有類(lèi)目及鏈接

https://book.douban.com/tag/
image.png

代碼

from pyquery import PyQuery as pq
import requests

headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}

#這里我還是使用requests庫(kù)作為網(wǎng)絡(luò)請(qǐng)求庫(kù),方便定制
resp = requests.get('https://book.douban.com/tag/', headers=headers)
tags_doc = pq(resp.text)

#獲取豆瓣讀書(shū)標(biāo)簽頁(yè)的標(biāo)簽列表蛛碌,此處返回的是PyQuery對(duì)象
tags_doc = pq(url='https://book.douban.com/tag/')

#查看https://book.douban.com/tag/的html數(shù)據(jù)信息
print(tags_doc.html())
#檢驗(yàn)發(fā)現(xiàn)總共有6個(gè)大類(lèi)(科技聂喇、經(jīng)管、生活、文化希太、流行文學(xué))
#print(len(tags_doc('.tagCol')))

"""
我們要獲取大類(lèi)下面的小類(lèi)名(如文學(xué)中包含小說(shuō)克饶、外國(guó)文學(xué)、雜文等)及小類(lèi)目的鏈接
"""

for a in tags_doc('.tagCol').items('a'):
    print(a)
    
"""
與上面打印的a是相同的
for tag in tags_doc('.tagCol'):
    for a in pq(tag).items('a'):
        print(a)
"""

我們整理下上面的代碼誊辉,寫(xiě)成一個(gè)專(zhuān)門(mén)獲取小類(lèi)目及鏈接的函數(shù)

def fetch_tags():
    """
    獲取豆瓣閱讀各個(gè)類(lèi)名的標(biāo)簽名及鏈接
    :return: 形如[(tag_name,link),(tag_name2,link2)...]的列表
    """
    headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
    # 獲取豆瓣讀書(shū)標(biāo)簽頁(yè)的標(biāo)簽列表矾湃,此處返回的是PyQuery對(duì)象
    resp = requests.get('https://book.douban.com/tag/',headers=headers)
    
    tags_doc = pq(resp.text)
    tagnames = []
    # 獲取class="tagCol"的table標(biāo)簽,提取table中的很多個(gè)a標(biāo)簽
    for tag in tags_doc('.tagCol').items('a'):
        #a標(biāo)簽中的href值
        #link = 'https://book.douban.com'+tag.attr('href')
        #a標(biāo)簽夾住的文本內(nèi)容
        tag_name = tag.text()
        tagnames.append(tag_name)
    return tagnames

二、獲取某個(gè)標(biāo)簽的書(shū)籍信息

以“小說(shuō)”類(lèi)書(shū)籍為例堕澄,網(wǎng)址是這樣的

#小說(shuō)第一頁(yè)網(wǎng)址
"https://book.douban.com/tag/小說(shuō)?start=0&type=T"

#小說(shuō)第二頁(yè)網(wǎng)址
"https://book.douban.com/tag/小說(shuō)?start=20&type=T"

邀跃。。蛙紫。#小說(shuō)第n頁(yè)的網(wǎng)址  (n-1)*20
"https://book.douban.com/tag/小說(shuō)?start={num}&type=T".format(num=(n-1)*20)
image.png

代碼

url = 'https://book.douban.com/tag/{tag}?start={num}&type=T'

resp = requests.get(url.format(tag='小說(shuō)',num=0))

p_doc = pq(resp.text)


"""
class="paginator"的div節(jié)點(diǎn)
選取div中為a的直接子節(jié)點(diǎn)
從所有的a節(jié)點(diǎn)中選擇最后一個(gè)a節(jié)點(diǎn)坞嘀。
獲取這個(gè)a節(jié)點(diǎn)的文本內(nèi)容,即為總的頁(yè)面數(shù)
"""
pages = p_doc('.paginator').children('a').eq(-1).text()

#獲取該標(biāo)簽所有的頁(yè)面網(wǎng)址
purls = []

for page in range(pages):
    purl = url.format(tag='小說(shuō)',num=page*20)
    purls.append(purl)

我們將上面的代碼整理為一個(gè)函數(shù)

def tag_page_urls(tag='小說(shuō)'):
    """
    獲取某類(lèi)標(biāo)簽所有的網(wǎng)址
    :param tag: 書(shū)籍小類(lèi)目名惊来,如小說(shuō)
    :return: 返回該類(lèi)目所有頁(yè)面的網(wǎng)址
    """
    headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}

    url = 'https://book.douban.com/tag/{tag}?start={num}&type=T'
    resp = requests.get(url.format(tag=tag, num=0),headers=headers)
    p_doc = pq(resp.text)
    
    pages = p_doc('.paginator').children('a').eq(-1).text()
    # 獲取該標(biāo)簽所有的頁(yè)面網(wǎng)址
    purls = []
    for page in range(int(pages)):
        purl = url.format(tag=tag, num=page * 20)
        purls.append(purl)
    return purls

三丽涩、獲取每個(gè)頁(yè)面中書(shū)籍的信息

獲取書(shū)籍具體信息,以小說(shuō)類(lèi)第一頁(yè)例子裁蚁,想辦法獲取該頁(yè)所有的書(shū)籍信息矢渊。以此類(lèi)推,換個(gè)網(wǎng)址枉证,其他的頁(yè)面的書(shū)籍信息也可以獲取矮男。

purl = 'https://book.douban.com/tag/小說(shuō)?start=0&type=T'

resp = requests.get(purl,headers=headers)

p_doc = pq(resp.text)

for book in p_doc.items('.info'):
    #print(type(book))  #<class 'pyquery.pyquery.PyQuery'>
    
    #找class=”info“的div
    #div的直接子節(jié)點(diǎn)
    #從子節(jié)點(diǎn)中找a標(biāo)簽
    #獲取a標(biāo)簽的title屬性值
    title = book.children('h2').find('a').attr('title')
    
    #出版社   獲取class=”info“的div的class=”pub“的子節(jié)點(diǎn)的文本內(nèi)容
    public = book.children('.pub').text()
    #評(píng)論數(shù)
    comments = book.find('.pl').text()
    #書(shū)籍簡(jiǎn)介  獲取class=”info“的div倒數(shù)第二個(gè)子節(jié)點(diǎn)的文本
    description = book.children().eq(-2).text()
    print(title,public,comments,description)
image.png

整理上面的代碼,封裝為函數(shù)

def books_detail(purl,writer):
    """
    獲取某頁(yè)面所有的書(shū)籍信息
    :param purl: 豆瓣閱讀某類(lèi)標(biāo)簽的某一頁(yè)面的網(wǎng)址
    :param writer: 這是從get_all_books_data函數(shù)中生成的writer室谚,用來(lái)存儲(chǔ)數(shù)據(jù)
    :return: 返回該頁(yè)面所有書(shū)籍的信息
    """
    headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
    resp = requests.get(purl,headers=headers)
    p_doc = pq(resp.text)
    for book in p_doc.items('.info'):
        #print(type(book))  #<class 'pyquery.pyquery.PyQuery'>
        title = book.children('h2').find('a').attr('title')
        #出版社
        public = book.children('.pub').text()
        # 評(píng)分
        rating = book.find('.rating_nums').text()
        #評(píng)論數(shù)
        comments = book.find('.pl').text()
        #書(shū)籍簡(jiǎn)介
        description = book.children().eq(-2).text()
        
        detail = (title,public,rating,comments,description)
        writer.writerow(detail)
        print(detail)

四毡鉴、豆瓣閱讀爬蟲(chóng)

獲取豆瓣所有書(shū)籍信息

def get_all_books_data(filename):
    """
    開(kāi)始愉快的爬數(shù)據(jù)
    :param filename: 保存數(shù)據(jù)的csv文件的文件名
    :return: 
    """
    import csv,time
    file = '{}.csv'.format(filename)
    with open(file,'a+',encoding='utf-8',newline='') as csvf:
        writer = csv.writer(csvf)
        writer.writerow(('書(shū)籍名','出版社','評(píng)論數(shù)','簡(jiǎn)述'))
        for tag in fetch_tags():

            for purl in tag_page_urls(tag=tag):
                print(purl)
                books_detail(purl=purl,writer=writer)
                time.sleep(1)
        
  get_all_books_data(filename='data')

全部代碼

def fetch_tags():
    """
    獲取豆瓣閱讀各個(gè)類(lèi)名的標(biāo)簽名及鏈接
    :return: 形如[(tag_name,link),(tag_name2,link2)...]的列表
    """
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
    # 獲取豆瓣讀書(shū)標(biāo)簽頁(yè)的標(biāo)簽列表,此處返回的是PyQuery對(duì)象
    resp = requests.get('https://book.douban.com/tag/', headers=headers)

    tags_doc = pq(resp.text)
    tagnames = []
    # 獲取class="tagCol"的table標(biāo)簽,提取table中的很多個(gè)a標(biāo)簽
    for tag in tags_doc('.tagCol').items('a'):
        # a標(biāo)簽中的href值
        # link = 'https://book.douban.com'+tag.attr('href')
        # a標(biāo)簽夾住的文本內(nèi)容
        tag_name = tag.text()
        tagnames.append(tag_name)
    return tagnames


def tag_page_urls(tag='小說(shuō)'):
    """
    獲取某類(lèi)標(biāo)簽所有的網(wǎng)址
    :param tag: 書(shū)籍小類(lèi)目名秒赤,如小說(shuō)
    :return: 返回該類(lèi)目所有頁(yè)面的網(wǎng)址
    """
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}

    url = 'https://book.douban.com/tag/{tag}?start={num}&type=T'
    resp = requests.get(url.format(tag=tag, num=0), headers=headers)
    p_doc = pq(resp.text)

    pages = p_doc('.paginator').children('a').eq(-1).text()
    # 獲取該標(biāo)簽所有的頁(yè)面網(wǎng)址
    purls = []
    for page in range(int(pages)):
        purl = url.format(tag=tag, num=page * 20)
        purls.append(purl)
    return purls


def books_detail(purl, writer):
    """
    獲取某頁(yè)面所有的書(shū)籍信息
    :param purl: 豆瓣閱讀某類(lèi)標(biāo)簽的某一頁(yè)面的網(wǎng)址
    :param writer: 這是從get_all_books_data函數(shù)中生成的writer猪瞬,用來(lái)存儲(chǔ)數(shù)據(jù)
    :return: 返回該頁(yè)面所有書(shū)籍的信息
    """
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
    resp = requests.get(purl, headers=headers)
    p_doc = pq(resp.text)
    for book in p_doc.items('.info'):
        # print(type(book))  #<class 'pyquery.pyquery.PyQuery'>
        title = book.children('h2').find('a').attr('title')
        # 出版社
        public = book.children('.pub').text()
        # 評(píng)分
        rating = book.find('.rating_nums').text()
        # 評(píng)論數(shù)
        comments = book.find('.pl').text()
        # 書(shū)籍簡(jiǎn)介
        description = book.children().eq(-2).text()

        detail = (title, public, rating, comments, description)
        writer.writerow(detail)
        print(detail)





def get_all_books_data(filename):
    """
    開(kāi)始愉快的爬數(shù)據(jù)
    :param filename: 保存數(shù)據(jù)的csv文件的文件名
    :return:
    """
    import csv, time
    file = '{}.csv'.format(filename)
    with open(file, 'a+', encoding='utf-8', newline='') as csvf:
        writer = csv.writer(csvf)
        writer.writerow(('書(shū)籍名', '出版社', '評(píng)論數(shù)', '簡(jiǎn)述'))
        for tag in fetch_tags():

            for purl in tag_page_urls(tag=tag):
                print(purl)
                books_detail(purl=purl, writer=writer)
                time.sleep(1)


get_all_books_data(filename='data')
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市入篮,隨后出現(xiàn)的幾起案子陈瘦,更是在濱河造成了極大的恐慌,老刑警劉巖潮售,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痊项,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡酥诽,警方通過(guò)查閱死者的電腦和手機(jī)鞍泉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)肮帐,“玉大人咖驮,你說(shuō)我怎么就攤上這事。” “怎么了游沿?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵饰抒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我诀黍,道長(zhǎng)袋坑,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任眯勾,我火速辦了婚禮枣宫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吃环。我一直安慰自己也颤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布郁轻。 她就那樣靜靜地躺著翅娶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪好唯。 梳的紋絲不亂的頭發(fā)上竭沫,一...
    開(kāi)封第一講書(shū)人閱讀 49,806評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音骑篙,去河邊找鬼蜕提。 笑死,一個(gè)胖子當(dāng)著我的面吹牛靶端,可吹牛的內(nèi)容都是我干的谎势。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼杨名,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼脏榆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起镣煮,我...
    開(kāi)封第一講書(shū)人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤姐霍,失蹤者是張志新(化名)和其女友劉穎鄙麦,沒(méi)想到半個(gè)月后典唇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胯府,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年介衔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骂因。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡炎咖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乘盼,我是刑警寧澤升熊,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站绸栅,受9級(jí)特大地震影響级野,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜粹胯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一蓖柔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧风纠,春花似錦况鸣、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至臭增,卻和暖如春愤估,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背速址。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工玩焰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芍锚。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓昔园,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親并炮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子默刚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容