一:爬蟲
1、爬取的目標
將讀書網(wǎng)上的書籍的基本信息,比如:封面、書名、作者、出版社、價格、出版時間、內(nèi)容簡介、作者簡介、書籍目錄、ISBN和標簽爬取出來,并將爬取的結(jié)果放入數(shù)據(jù)庫中,方便存儲。
2、網(wǎng)站結(jié)構(gòu)
???
圖1讀書網(wǎng)書籍類別詳情
此次實驗爬取讀書網(wǎng)頁面中文學、小說、傳記、青春文學、藝術(shù)、散文隨筆、勵志、人文社科、經(jīng)濟管理、勵志十大類書籍。
每一類書籍包括書名、價格、作者、出版社、ISDN、出版時間、封面以及書籍簡介、作者簡介、書目錄和書籍所屬類別。頁面具體情況如圖2所示。
圖2讀書網(wǎng)書籍屬性設計詳情
3、爬蟲技術(shù)方案
1)、所用技術(shù):
?????????網(wǎng)站解析的使用的是Xpath、數(shù)據(jù)庫存儲使用的是pymysql。
2)、爬取步驟:
????(1)、分析目標網(wǎng)站:了解頁面結(jié)構(gòu);
(2)、獲取頁面內(nèi)容:使用python中的requests庫來獲取頁面內(nèi)容;
(3)、定位頁面:使用Xpath定位我們所需要的數(shù)據(jù)的位置;
(4)、連接數(shù)據(jù)庫:創(chuàng)建數(shù)據(jù)連接,放入自己數(shù)據(jù)庫的端口、用戶和密碼等數(shù)據(jù),使得連接上自己的數(shù)據(jù)庫,將爬取好的數(shù)據(jù)返給數(shù)據(jù)庫中,方便存儲;
(5)、關(guān)閉連接:關(guān)閉數(shù)據(jù)庫連接。
4、爬取過程:
???
1)、常量定義
????
此處定義了網(wǎng)頁后綴END=‘.html’用于進行網(wǎng)頁拼接。
Start_Page = 1 定義爬取起始頁碼,end_Page = 10 定義爬取結(jié)束頁碼。
Base_url 用于設置爬取網(wǎng)頁的基礎網(wǎng)站,進行后續(xù)網(wǎng)頁拼接。
Book_type={},該字典設置爬取書籍類別。
Header={},該字典進行請求頭設置。
2)、設置游標,連接數(shù)據(jù)庫,再使用for循環(huán),確保書籍能夠循環(huán)爬取,最后將爬取完畢的數(shù)據(jù)放入數(shù)據(jù)庫中,最后關(guān)閉數(shù)據(jù)庫的連接。
??
???3)、一級鏈接爬取,接收參數(shù)基本網(wǎng)頁地址、書籍類型、網(wǎng)頁頁數(shù)后,再使用requests庫中r.get(url=url,headers=header)發(fā)送請求,使用response接收請求數(shù)據(jù)。
???
4)、二級鏈接爬取,在數(shù)據(jù)獲取步驟,進行更細致的xpath語句書寫。
使用try-except語句提高程序健壯性,返回一個書籍信息字典。
??????
??????5)、保存數(shù)據(jù),創(chuàng)建游標,編寫sql語言,之后執(zhí)行sql語言,執(zhí)行成功就插入所給的表,如果執(zhí)行失敗則輸出插入失敗。
??????
5、爬蟲結(jié)果
二:預處理
-
刪除列
1)、新建轉(zhuǎn)換,之后使用表輸入,將MySQL文件中的表輸入kettle。需要連接數(shù)據(jù)庫的類型是MySQL,主機名稱是localhost、用戶是root、密碼是root、端口號是3306。
????
之后進行字段獲取。
2)、選擇轉(zhuǎn)換中的字段選擇進行列刪除,將dictroy這個列進行刪除。
2、選擇轉(zhuǎn)換中的增加常量,增加remainder這一列,查詢書籍賣出剩余的情況。
????
-
、最后選擇文本文件輸出,將處理好的數(shù)據(jù)輸出,輸出的格式是csv文件,分割符用逗號隔開,編碼用UTF-8J進行轉(zhuǎn)碼,防止輸出文件中有亂碼。文本文件命名為姓名_處理完成_csv。
4、預處理完全處理全流程
文章來源:http://www.zghlxwxcb.cn/news/detail-811688.html
三、爬蟲源代碼
import re
import requests
from lxml import etree
import pymysql
import datetime
"""
爬取一個網(wǎng)站
1.獲得數(shù)據(jù)不小于一千條
2.每條數(shù)據(jù)屬性不小于10
"""
END = '.html'
start_Page = 1
end_Page = 10
base_url = 'https://www.dushu.com'
# 以字典形式保存每一類對應的網(wǎng)頁數(shù)字
book_type = {"文學": 1077, "小說": 1078, "傳記": 1081, "青春文學": 1079,
"藝術(shù)": 1082, "散文隨筆": 1163, "鑒賞": 1222, "人文社科": 1003,
"經(jīng)濟管理": 1004, "勵志": 1094
}
header = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
}
def get_one_bookInfo_link(base_url, _type, page):
# url 控制爬取的書籍類型、網(wǎng)頁頁數(shù)
url = base_url+'/book/'+str(_type)+'_'+str(page)+END
# print(url)
response = requests.get(url=url, headers=header)
if response.status_code == 200:
htmlTEXT = response.content.decode(response.apparent_encoding)
html = etree.HTML(htmlTEXT)
bookLinke_List = html.xpath('//div[@class="container margin-top"]//div[@class="bookslist"]/ul/li/div[@class="book-info"]/h3/a/@href')
return bookLinke_List
else:
print("請求失敗")
def get_oneBook_info(bookLinke):
url = base_url + bookLinke
content = requests.get(url=url, headers=header)
if content.status_code == 200:
info = etree.HTML(content.content.decode(content.apparent_encoding))
# 獲取書籍詳細信息,十個
try:
img = info.xpath('//div[@class="bookdetails-left"]/div[@class="book-pic"]//img/@src')[0] # 封面
title = info.xpath('//div[@class="bookdetails-left"]/div[@class="book-pic"]//img/@alt')[0] # 書名
author = info.xpath('//div[@id="ctl00_c1_bookleft"]/table//tr[1]//td[2]/text()')[0] # 作者
publish = info.xpath('//div[@id="ctl00_c1_bookleft"]/table//tr[2]//td[2]/text()')[0] # 出版社
temp_price = info.xpath('//div[@id="ctl00_c1_bookleft"]/p/span/text()')[0] # 價格
price = temp_price.split('¥')[1]
time = info.xpath('//div[@class="bookdetails-left"]/div[@class="book-details"]/table//tr[1]/td[@class="rt"][2]/text()')[0] # 出版時間
cont = info.xpath('//div[@class="container margin-top"]//div[contains(@class, "book-summary")][1]/div/div/text()')[0] # 內(nèi)容簡介
blurb = info.xpath('//div[@class="container margin-top"]//div[contains(@class, "book-summary")][2]/div/div/text()')[0] # 作者簡介
directory = info.xpath('//div[@class="container margin-top"]//div[contains(@class, "book-summary")][3]/div/div/text()')[0] # 書籍目錄
isbn = info.xpath('//div[@class="bookdetails-left"]/div[@class="book-details"]/table//tr[1]/td[@class="rt"][1]/text()')[0] # ISBN
label = info.xpath('//div[@id="ctl00_c1_bookleft"]/table//tr[4]//td[2]/text()')[0] # 標簽
# 使用字典保存一本書籍的信息
book_info = {
"img": img,
"title": title,
"author": author,
"publish": publish,
"price": price,
"time": time,
"cont": cont,
"blurb": blurb,
"directory": directory,
"isbn": isbn,
"label": label
}
return book_info
except Exception as e:
print("爬取時單本書籍獲取出現(xiàn)錯誤:", e, "\n發(fā)生錯誤地址為:"+url)
err_info = {
"img": 'https://a.dushu.com/img/n200.png',
"title": 'titleEro',
"author": 'authorEro',
"publish": 'publishEro',
"price": '00.00',
"time": '2001-01-01',
"cont": 'contEro',
"blurb": 'blurbEro',
"directory": 'directoryEro',
"isbn": 'isbnEro',
"label": 'labelEro'
}
return err_info
else:
print("請求失敗")
def set_BookInfo_ToMySql(book_info, db):
# print(book_info.values())
cursor = db.cursor()
# sql語句
sql = "INSERT INTO book(img,title,author,publish,price,time,cont,blurb,directory,isbn,label) VALUES " \
"('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')"\
%(book_info["img"], book_info["title"], book_info["author"], book_info["publish"],
book_info["price"], book_info["time"], book_info["cont"], book_info["blurb"],
book_info["directory"], book_info["isbn"], book_info["label"])
print(book_info.values())
try:
# 執(zhí)行sql語句
if cursor.execute(sql):
print('插入數(shù)據(jù)成功')
# 提交到數(shù)據(jù)庫執(zhí)行
db.commit() # 持久化
except Exception as e:
# 如果發(fā)生錯誤則回滾
print("插入失敗", e)
db.rollback()
def main():
# 用于存儲計算數(shù)據(jù)爬取數(shù)量
count = 0
# 連接數(shù)據(jù)庫
db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='pachong')
# 開啟爬取程序
for type in book_type: # 控制爬取書籍的類別
for i in range(start_Page, end_Page+1): # 控制每一類爬取的頁數(shù)
# 每一個網(wǎng)頁的書籍的二級連接
bookLinke_List = get_one_bookInfo_link(base_url=base_url, _type=book_type[type], page=i)
if bookLinke_List:
for link in bookLinke_List:
print(link)
info = get_oneBook_info(link)
info['label'] = type
# print(info)
set_BookInfo_ToMySql(book_info=info, db=db)
count += 1
else:
print("爬取內(nèi)容為空")
# 數(shù)據(jù)插入完成后關(guān)閉數(shù)據(jù)庫
if db:
db.close()
print("關(guān)閉數(shù)據(jù)庫成功,程序結(jié)束")
else:
print("數(shù)據(jù)加載成功,數(shù)據(jù)庫未關(guān)閉")
return count
if __name__ == '__main__':
print("Run...")
# 獲取開始時間
start_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='movie')
# info = get_oneBook_info('/book/13981332/')
# set_BookInfo_ToMySql(info, db=db)
# db.close()
print("已爬取書籍數(shù)量:", main())
# 獲取結(jié)束時間
end_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print("程序結(jié)束{}\n運行開始時間:{}".format(end_time, start_time))
?文章來源地址http://www.zghlxwxcb.cn/news/detail-811688.html
到了這里,關(guān)于基于爬蟲和Kettle的書籍信息采集與預處理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!