本任務(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/
代碼
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)
代碼
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)
整理上面的代碼,封裝為函數(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')