使用python爬豆瓣書單

<blockquote>
<p>背景介紹:非計算機專業,具有一點python編程基礎。 曾自學廖雪峰的《笨辦法學 Python(第四版)》、網易公開課《麻省理工學院公開課:計算機科學及編程導論》(以python為開發工具),另外購買了紙質版《python核心編程》以便遇到問題查看。
爬蟲相關書籍看過《OReilly.Web.Scraping.with.Python》</p>
<p>目的:爬取豆瓣書籍信息,包括書名、作者、譯者、出版社及時間、評分人數及星星等級,并存儲于mysql數據庫。</p>
<p>使用的工具:python3.5,jupyter notebook,sublime text,mysql。</p>
</blockquote>
<h3>個人理解爬蟲過程主要分為三個步:</h3>
<ul>
<li>獲取網頁內容 </li>
<li>解析網頁內容</li>
<li>存儲爬下來的數據</li>
</ul>
<h3>(1)獲取網頁內容</h3>
<blockquote>
<p>關鍵在于把爬蟲模擬成瀏覽器,發送請求。
涉及到的知識:http相關基礎知識、cookie、session、幾個python的包requests、beautifulsoup等</p>
</blockquote>
<p>1、import requests、beautifulsoup 庫。獲取瀏覽器headers(可在瀏覽器開發工具請求報文中看),這一步是爬蟲偽裝成瀏覽器。根據具體情況看是否需要cookie或session。</p>
<pre><code>import requests
from bs4 import BeautifulSoup
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36","Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8"}
url="https://book.douban.com/"
session=requests.session()
</code></pre>

<p>2、獲取網頁內容。涉及到知識:http相關知識,beautifulsoup、requests包,函數:beautifulsoup(),其中‘lxml’格式需要自己另外安裝,findall()及find()。</p>
<pre><code>def get_Content(url):
res=session.get(url,headers=headers)
req=BeautifulSoup(res.content,'lxml')
book_content=req.findAll("div",{"class":"info"})
return book_content
</code></pre>

<h3>(2)解析網頁內容</h3>
<blockquote>
<p>涉及到知識點:正則表達式、數據類型的轉換、for循環語句、find()and findall()、get_text()函數、sub()、replace()、join()、split()等</p>
</blockquote>
<p>1、import re(正則表達式庫),遍歷已經獲取的頁面內容(在get<em>content函數中返回,其中findall函數返回的數據類型是list,這點跟find函數有所區別)通過find、get</em>text函數獲取需要的書籍信息,數據類型為字符型str。由于獲取到的內容的格式,并不是最終想要的格式,需要進行數據清洗,包括去掉\n,多余的空白、括號、還有字段“4524人評價”需要提取“4524”并存儲為數值型。對于為什么需要判斷if not rate?是由于部分數據由于評價人員過少,缺失rating內容,這時候令rating=0,否則爬蟲爬到這本書的時候會報錯停止,最后通過float()將rating轉換成浮點型數值。針對"234評價"及"少于10人評價"情況的處理,用spilt(),跟正則表達式\D+(非數值)將數字跟漢字分開,再通過join只留下人數并轉換成INT整型。</p>
<pre><code>import re
def get_items(book_content):
global Tag
for i in book_content:
title=get_cleandata(i.find("a").get_text())
tran=get_cleandata(i.find("div",{"class":"pub"}).get_text())
rate=i.find("span",{"class":"rating_nums"})
if not rate:
rating=0
else:
rating=float(get_cleandata(rate.get_text()))
pl=int(''.join(re.split('\D+',get_cleandata(i.find("span",{"class":"pl"}).get_text()))))
store(Tag,title,tran,rating,pl)
def get_cleandata(data):
cleandata=re.sub("\n+","",data)
cleandata=cleandata.replace("(","")
cleandata=cleandata.replace(")","")
cleandata=re.sub(" +","",cleandata)
return cleandata
</code></pre>

<p>2、獲取所有需要爬取的url,一般有集中方式獲取:</p>
<blockquote>
<p>1.獲取“下一頁”的url,不斷的循環獲取,爬完一頁接著一頁。直到獲取下一頁的url為空停止。</p>
<p>2、分析不同頁數的url,找出規律,例如豆瓣讀書,下一頁的參數都是增加20(https://book.douban.com/tag/小說?start=20&type=T),這樣子就可以列出所有url,一直爬到返回的頁面內容為空停止。</p>
<p>我采用的是第二種辦法</p>
</blockquote>
<p>1、首先,觀察頁數最大值找到合適的值,觀察到豆瓣最大的頁數是99</p>
<pre><code>a=[a*20 for a in range(0,100)]
</code></pre>

<p>url參數的增加,通過urllib.parse.urlencode來增加。if not content 停止循環。最后通過time.sleep()控制循環時間,控制請求速度,模擬人點擊頁面,避免反爬策略。</p>
<pre><code>import import urllib.parse
import time
def get_Start(url):
global Tag
for i in Tag:
a=[a*20 for a in range(0,100)]
for r in a:
time.sleep(3)
values={"type":"T",'start':r}
data=urllib.parse.urlencode(values)
a=url+"tag/"+i+'?'+data
content=get_Content(a)
if not content:
break
else:
get_items(content)
</code></pre>

<p>其中還有獲取Tag的值,由于不想爬全部的書籍,就直接通過修改Tag的內容來爬感興趣的:</p>
<pre><code>#def get_Tab(url):
#r=session.get(url+"/tag/",headers=headers)
#bsObj=BeautifulSoup(r.content,'lxml')
#Tag_contents=bsObj.findAll("a",href=re.compile("^/tag/.*"))
#Tag=[tag.get_text()for tag in Tag_contents]
#return Tag
Tag=['哲學']
</code></pre>

<h3>(3)存儲爬下來的信息</h3>
<blockquote>
<p>需要安裝mysql,一些數據庫操作的語句及基本知識</p>
</blockquote>
<p>1、首先,import pymysql庫及設置好連接,在mysql里面建立好database及相關的表</p>
<pre><code>import pymysql
conn = pymysql.connect(host='localhost',user='root',passwd='lym*',db='mysql',charset='utf8')
cur = conn.cursor()
cur.execute("USE douban")
</code></pre>

<p>2、調用def store()函數存儲相關的數據</p>
<pre><code>def store(Tag,title,tran,rating,pl):
cur.execute("insert into philosophy(Tag,book,content,point,comment_num) values(%s,%s,%s,%s,%s)",(Tag,title,tran,rating,pl))
cur.connection.commit()
</code></pre>

<h3>總結,整一個爬蟲流程是先import相關的庫,設置好開始的headers、開始url,然后get<em>Start(url),獲取需要爬的url,再調用get</em>items(),獲取頁面內容,通過get_cleandata()對數據進行清洗,最后調用store()進行存儲爬下來的數據</h3>
<h3>下次,搞搞多線程</h3>

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容