一. allitebooks網(wǎng)站鏈接:http://www.allitebooks.com/
二. 具體流程
allitebooks的網(wǎng)頁(yè)以翻頁(yè)的形式展現(xiàn)下一頁(yè)的書(shū)籍信息贷币,通過(guò)對(duì)鏈接的比較,發(fā)現(xiàn)url的規(guī)律:"http://www.allitebooks.com/page/{}/".format(index)啄糙,其中index表示頁(yè)碼放刨,可以根據(jù)這個(gè)規(guī)則決定爬取多個(gè)網(wǎng)頁(yè)的數(shù)據(jù)工秩;
根據(jù)url去請(qǐng)求網(wǎng)頁(yè)數(shù)據(jù),并返回指定編碼‘utf-8’的網(wǎng)頁(yè)數(shù)據(jù)进统,用戶(hù)下一步的網(wǎng)頁(yè)數(shù)據(jù)的解析助币;
-
對(duì)網(wǎng)頁(yè)數(shù)據(jù)進(jìn)行解析,本文用xpath和beautifulsoup的方法都實(shí)現(xiàn)了螟碎,獲取的信息有書(shū)名眉菱、作者、書(shū)詳情鏈接掉分、簡(jiǎn)介俭缓,保存到一個(gè)list中,用于后續(xù)的數(shù)據(jù)保存酥郭;
網(wǎng)頁(yè)解析 將解析完成的數(shù)據(jù)保存到csv中华坦。
代碼如下:
# -*- coding: utf-8 -*-
import requests
from lxml import etree
import csv
from bs4 import BeautifulSoup
import time
class BookSpider(object):
def __init__(self):
# 初始化數(shù)據(jù),請(qǐng)求的url,headers和保存最終結(jié)果的result變量
# 頁(yè)面是翻頁(yè)加載數(shù)據(jù)的不从,翻頁(yè)的鏈接規(guī)則是www.allitebooks.com/page/n/ ,其中n表示第n頁(yè)的數(shù)據(jù)
self.url = "http://www.allitebooks.com/page/{}/"
self.headers = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'}
# 需要爬取的信息有書(shū)名book_name惜姐,作者author,書(shū)的詳情鏈接url和書(shū)的簡(jiǎn)介summary
self.result = [['book_name', 'author', 'url', 'summary']]
# 獲取需要請(qǐng)求的url椿息,返回一個(gè)List的url去請(qǐng)求相關(guān)頁(yè)面的數(shù)據(jù)
def get_url_list(self):
url_list = []
for index in range(1,8):
url_list.append((self.url).format(index))
return url_list
# 根據(jù)給到的url去請(qǐng)求相關(guān)頁(yè)面的數(shù)據(jù)
def get_data(self, url):
response = requests.get(url=url, headers=self.headers)
return response.content.decode('utf-8')
# 使用xpath對(duì)請(qǐng)求的數(shù)據(jù)進(jìn)行解析
def parse_data_xpath(self, data):
xpath_data = etree.HTML(data)
# 獲取包含了書(shū)名歹袁、作者、鏈接寝优、簡(jiǎn)介的模塊列表宇攻,對(duì)列表進(jìn)行遍歷,獲取相關(guān)的信息
articles = xpath_data.xpath('//div[@class="entry-body"]')
for article in articles:
article_list = []
# 獲取書(shū)名
book_name = article.xpath('.//h2/a/text()')[0]
# 獲取作者
author = article.xpath('.//h5[@class="entry-author"]/a/text()')[0]
# 獲取書(shū)的詳情鏈接
url = article.xpath('.//h2/a/@href')[0]
# 獲取書(shū)的簡(jiǎn)介
summary = article.xpath('./div[@class="entry-summary"]/p/text()')[0]
# 組合成一個(gè)list倡勇,添加到成員變量result中逞刷,用于最后的csv保存
article_list = [book_name, author, url, summary]
self.result.append(article_list)
# 使用BeautifulSoup對(duì)請(qǐng)求的數(shù)據(jù)進(jìn)行解析
def parse_data_bs4(self, data):
bs4_data = BeautifulSoup(data, 'lxml')
# 獲取包含了書(shū)名、作者妻熊、鏈接夸浅、簡(jiǎn)介的模塊列表,對(duì)列表進(jìn)行遍歷扔役,獲取相關(guān)的信息
articles = bs4_data.select('.entry-body')
for article in articles:
article_list=[]
book_name = article.select('.entry-title a')[0].get_text()
author = article.select('.entry-author a')[0].get_text()
url = article.select('.entry-title a')[0].get('href')
summary = article.select('.entry-summary p')[0].get_text()
article_list = [book_name, author, url, summary]
self.result.append(article_list)
print(len(self.result))
# 使用csv的方式保存result中的數(shù)據(jù)
def save_data(self):
# 需要指定encoding='utf-8',不然會(huì)有編碼報(bào)錯(cuò)(windows專(zhuān)屬哈哈)
# 因?yàn)槭鞘褂玫膒ython3版本帆喇,所以需要newline='',不指定的話(huà)保存的csv中,每行后面都會(huì)有個(gè)空行
book_fp = open("book_info.csv", 'w', newline='', encoding='utf-8')
writer = csv.writer(book_fp)
writer.writerows(self.result)
book_fp.close()
# 執(zhí)行數(shù)據(jù)爬取和保存的操作:獲取需要爬取的網(wǎng)頁(yè)的鏈接-->根據(jù)鏈接獲取網(wǎng)頁(yè)數(shù)據(jù)-->對(duì)網(wǎng)頁(yè)數(shù)據(jù)進(jìn)行解析-->保存解析后的數(shù)據(jù)
def run(self):
# 獲取需要爬去數(shù)據(jù)的url
url_list = self.get_url_list()
for url in url_list:
# 獲取網(wǎng)頁(yè)數(shù)據(jù)
data = self.get_data(url)
# 對(duì)網(wǎng)頁(yè)數(shù)據(jù)進(jìn)行解析亿胸,可以使用xpath的parse_data_xpath()或者BeautifulSoup的parse_data_bs4進(jìn)行解析坯钦,獲取相關(guān)數(shù)據(jù)
self.parse_data_bs4(data)
# 休眠1秒
time.sleep(1)
# 保存爬去的數(shù)據(jù)
self.save_data()
BookSpider().run()
結(jié)果:
三.遇到的問(wèn)題
-
保存的csv文件中多了一行空行
保存的csv文件中多了一行空行
在windows這種使用\r\n的系統(tǒng)里预皇,不用newline=‘’的話(huà),會(huì)自動(dòng)在行尾多添加個(gè)\r婉刀,導(dǎo)致多出一個(gè)空行吟温,即行尾為\r\r\n
參考鏈接:https://blog.csdn.net/pfm685757/article/details/47806469
解決方法:在打開(kāi)的文件流中添加newline='',如:book_fp = open("book_info.csv", 'w', newline='', encoding='utf-8')
- 保存數(shù)據(jù)到csv時(shí)遇到UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 444: illegal multibyte sequence的報(bào)錯(cuò)
在window平臺(tái)突颊,文件的默認(rèn)編碼是gbk鲁豪, 此時(shí)如果寫(xiě)入的字符串的編碼是utf-8,則會(huì)引發(fā)編碼報(bào)錯(cuò)
參考鏈接:http://www.itdaan.com/blog/2018/04/19/cef6ddb3809354ac175c64c228fe51fb.html
解決方法:指定編碼格式encoding='utf-8'的情況下打開(kāi)寫(xiě)入流:book_fp = open("book_info.csv", 'w', newline='', encoding='utf-8')
- summary的文本數(shù)據(jù)過(guò)長(zhǎng)律秃,通過(guò)Excel 打開(kāi)csv的時(shí)候爬橡,數(shù)據(jù)顯示在一個(gè)單元格上
數(shù)據(jù)顯示在一個(gè)單元格上
參考鏈接:https://blog.csdn.net/caolaosanahnu/article/details/7351776
解決方法:目前來(lái)看應(yīng)該是excel打開(kāi)csv時(shí)會(huì)有的格式的問(wèn)題,暫時(shí)不是很清楚為什么會(huì)出現(xiàn)這個(gè)問(wèn)題棒动,但是將csv文件用記事本的方式打開(kāi)之后糙申,另存為時(shí)選擇utf-8的編碼格式,再打開(kāi)另存為的文件船惨,是可以看到整齊的數(shù)據(jù)的郭宝。
代碼鏈接:https://github.com/zhuyecao/kaikeba/tree/master/kaikeba/allitebook