0引言
學(xué)爬蟲(chóng),拿平??葱≌f(shuō)的綠色網(wǎng)站下手。
爬取的數(shù)據(jù)主要分為兩部分,收藏榜的小說(shuō)信息和小說(shuō)詳情頁(yè)的部分?jǐn)?shù)據(jù)。
1url解析
1.1收藏榜url
????????通過(guò)點(diǎn)擊榜單上側(cè)選項(xiàng)(其實(shí)也可以用拼音猜一猜),觀察url變化,尋找規(guī)律。如fw指代范圍,fbsj指代發(fā)表時(shí)間,ycx指代原創(chuàng)性,以此類推??梢酝ㄟ^(guò)改變其后的數(shù)字,來(lái)改變榜單范圍。而最重要的翻頁(yè)就通過(guò)改變page=后的頁(yè)碼。
? ? ? ? 我沒(méi)什么要先定的范圍,就只更改page。
2.1小說(shuō)詳情頁(yè)url
? ? ? ? 隨意點(diǎn)擊任意小說(shuō)詳情頁(yè),可以看到主要區(qū)別就在于最后novelid的一串?dāng)?shù)字,看起來(lái)沒(méi)有什么規(guī)律的數(shù)字。
? ? ? ? 但是通過(guò)后面的頁(yè)面分析,可以看到小說(shuō)詳情頁(yè)的url其實(shí)就包含在html中,只要記錄下之后再轉(zhuǎn)接即可。
2頁(yè)面元素解析
2.1收藏榜
?????????鼠標(biāo)右鍵查看審查元素,觀察。
? ? ? ? 可以看到,整個(gè)收藏榜信息均在一個(gè)table之內(nèi),一行是一個(gè)tr,每格是一個(gè)td。
<tr>
<td align="left">
<a href="oneauthor.php?authorid=966799" target="_blank">木蘇里</a>
</td>
<td align="left">
<a href="onebook.php?novelid=3419133" target="_blank" title="簡(jiǎn)介:并肩炸考場(chǎng)
標(biāo)簽:強(qiáng)強(qiáng) 無(wú)限流 相愛(ài)相殺 未來(lái)架空">全球高考</a>
</td>
<td align="center">
原創(chuàng)-純愛(ài)-近代現(xiàn)代-劇情 </td>
<td align="center">
輕松 </td>
<td align="center">
<font color="red">完結(jié)</font> </td>
<td align="right">589514</td>
<td align="right">35908325376</td>
<td align="center">2018-10-10 20:03:00</td>
</tr>
????????以第一部作品為例,按順序,可以爬取到作者(木蘇里)、作品詳情頁(yè)鏈接(oneauthor.php?authorid=966799)、簡(jiǎn)介+標(biāo)簽(簡(jiǎn)介:并肩炸考場(chǎng)
標(biāo)簽:強(qiáng)強(qiáng) 無(wú)限流 相愛(ài)相殺 未來(lái)架空)、作品(全球高考)、類型(原創(chuàng)-純愛(ài)-近代現(xiàn)代-劇情)、風(fēng)格(輕松)、進(jìn)度(完結(jié))、字?jǐn)?shù)(589514)、作品積分(35908325376)、發(fā)表時(shí)間(2018/10/10 20:03:00)。
? ? ? ? 整個(gè)表格都比較有規(guī)律,先f(wàn)indall tr,再根據(jù)html寫出對(duì)應(yīng)的正則compile。
2.2小說(shuō)詳情頁(yè)
? ? ? ? 詳情頁(yè)主要準(zhǔn)備爬取三個(gè)地方:文案、文章基本信息、章節(jié)表格結(jié)尾數(shù)據(jù)
????????1)文案
? ? ? ? 2)作品視角、是否出版、簽約狀態(tài)
? ? ? ? ?3)總書(shū)評(píng)數(shù)、當(dāng)前被收藏?cái)?shù)、營(yíng)養(yǎng)液數(shù)
? ? ? ? ?同樣是查看審查元素,寫出正則表達(dá)式,但在這里遇到了不少問(wèn)題:
? ? ? ? 1)審查元素與源代碼有差別
? ? ? ? 部分?jǐn)?shù)據(jù),如非v章節(jié)章均點(diǎn)擊數(shù),審查元素有,但是源代碼里是空白:
? ? ? ? ?這是個(gè)動(dòng)態(tài)元素,后來(lái)找到了解決辦法,但是要再次跳轉(zhuǎn)頁(yè)碼過(guò)于麻煩,所以決定放棄這個(gè)數(shù)據(jù)。
? ? ? ? 2)區(qū)域html差別大
? ? ? ? 爬取的三個(gè)地方,不像收藏榜是在一個(gè)table里,很難findall先鎖定一個(gè)大區(qū)域,嘗試之后,東拼西湊,文案和書(shū)評(píng)收藏?cái)?shù)用compile,文章基本信息里,先f(wàn)indall了ul。
? ? ? ? 3)是否出版扒不下來(lái)
? ? ? ? ?原本想把title里的文字給扒下來(lái),但是無(wú)論如何compile都是空白,最后草率地寫了個(gè)if else簡(jiǎn)單判斷,手動(dòng)append上是否出版的信息。
3cookie
? ? ? ? 晉江不登錄的話,只讓爬取前十頁(yè)的數(shù)據(jù),十頁(yè)以后會(huì)有登錄提示,爬蟲(chóng)也自動(dòng)斷了,上網(wǎng)找到了解決方法,登錄晉江賬號(hào)后,查看審查元素,并刷新頁(yè)面,找到如下所示:?
? ? ? ? ?將cookie復(fù)制,加到爬蟲(chóng)的請(qǐng)求頭中。
4代碼
import requests
from bs4 import BeautifulSoup
import time
import re
import xlwt
t1 = time.time()
def main(savepath):
count=0
for page in range(1,501):
url = get_url(page)
headers = {
'cookie': '你的cookie'}
html = requests.get(url, headers=headers)
html.encoding = html.apparent_encoding
try:
datalist = getData(html.content)
except:
print("爬取失?。?, page)
continue
if len(datalist) == 0:
break
saveData(savepath,datalist,count)
count+=len(datalist)
print(page)
print(count)
#time.sleep(3)
def get_url(page):
url = f"https://www.jjwxc.net/bookbase.php?fw0=0&fbsj0=0&ycx0=0&xx0=0&mainview0=0&sd0=0&lx0=0&fg0=0&bq=-1&sortType=4&isfinish=0&collectiontypes=ors&page={page}"
return url
#提取收藏榜數(shù)據(jù)的正則表達(dá)式
findAuthor = re.compile(r'">(.*?)</a>',re.U)
findName = re.compile(r'">(.*?)</a>',re.U)
findBookLink = re.compile(r'<a href="(.*?)"')
findTitle = re.compile(r"<a.*?href=.*?<\/a>", re.I|re.S|re.M)
findType = re.compile(r'<td align="center">(.*?)</td>', re.S|re.M)
findStyle = re.compile(r'<td align="center">(.*?)</td>', re.S|re.M)
findPro = re.compile(r'<td align="center">(.*?)</td>', re.S|re.M)
findSize = re.compile(r'<td align="right">(\d+)</td>')
findPoint = re.compile(r'<td align="right">(\d+)</td>')
findTime = re.compile(r'<td align="center">(.*?)</td>')
def getData(document):
datalist = []
soup = BeautifulSoup(document, "html.parser")
i = 0
for item in soup.findAll('tr'):
data = [] # 保存一本書(shū)的所有信息
item = str(item)
Author = re.findall(findAuthor, item)# 提取作者名
Name = re.findall(findName, item)# 提取文名
BookLink = re.findall(findBookLink, item)# 提取文章鏈接
Title = re.findall(findTitle, item)# 提取標(biāo)簽
Type = re.findall(findType, item)# 提取類型
Style = re.findall(findStyle, item)# 提取風(fēng)格
Pro = re.findall(findPro, item)# 提取進(jìn)度
Size = re.findall(findSize, item)# 提取字?jǐn)?shù)
Point = re.findall(findPoint, item)# 提取積分
Time = re.findall(findTime, item)# 提取發(fā)表時(shí)間
if i:
data.append(Author[0])
data.append(Name[1])
BookLink[1]='http://www.jjwxc.net/' + BookLink[1]
data.append(BookLink[1])
Title[1]=re.findall(r'title="(.*?)"', Title[1], re.S|re.M)
data.append(Title[1])
data.append(Type[0].strip())
data.append(Style[1].strip())
if '</font>' in Pro[2]:
Pro[2]=re.findall(r'>(.*?)</font>', Pro[2])
data.append(Pro[2])
else:
data.append(Pro[2].strip())
data.append(int(Size[0]))
data.append(int(Point[1]))
data.append(Time[0])
#進(jìn)入小說(shuō)詳情頁(yè),爬取相關(guān)數(shù)據(jù)
try:
detail(BookLink[1],data)
except:
print("爬取失?。?, BookLink[1])
continue
datalist.append(data)
i = 1
return datalist
def getURL(url):
headers = {
'User-Agent': 'Mozilla/5.0 (MSIE 10.0; Windows NT 6.1; Trident/5.0)'
}
response = requests.get(url,headers = headers)
response.encoding = 'gbk'
time.sleep(0.2)
if response.status_code == 200:
return response.text
return None
def detail(url,data):
html = getURL(url)
soup = BeautifulSoup(html, "html.parser")
#爬取書(shū)評(píng)、收藏、營(yíng)養(yǎng)液數(shù)
comment = re.compile('<tr>.*?<td.*?>.*?<div align="center">.*?<span.*?>(.*?)</span>.*?<span.*?>(.*?)</span>.*?<span.*?>(.*?)</span>.*?<span.*?>(.*?)</span>.*?',re.S)
items = re.findall(comment,html)
for j in items:
data.append(j[1])#書(shū)評(píng)數(shù)
data.append(j[2])#當(dāng)前被收藏?cái)?shù)
data.append(j[3])#營(yíng)養(yǎng)液數(shù)
#爬取文案
copywriting = re.compile('<tr>.*?<div id="novelintro" itemprop="description">(.*?)</div>',re.S)
items = re.findall(copywriting,html)
#value = items[0].replace('<br>', '').replace(' ', '')
pattern = re.compile(r'<[^>]+>',re.S)
value = pattern.sub('', items[0])
data.append(value)
# 爬取作品視角、出版、簽約狀態(tài)
result_list = soup.find_all('ul',attrs={'name':'printright'})
for results in result_list:
result=str(results)
infor = re.compile('</span>(.*?)</li>',re.S|re.M)
items = re.findall(infor,result)
data.append(items[2].strip())#作品視角
if 'img' in items[7]:#是否出版
data.append("已出版")
else:
data.append("尚未出版")
items[9]=re.findall(r'>(.*?)</font>', items[9])#是否簽約
data.append(items[9][0])
workbook = xlwt.Workbook(encoding='utf-8',style_compression=0)
worksheet = workbook.add_sheet('晉江', cell_overwrite_ok=True)
col = ("作者","作品","鏈接","標(biāo)簽","類型","風(fēng)格","進(jìn)度","字?jǐn)?shù)","作品積分","發(fā)表時(shí)間","總書(shū)評(píng)數(shù)","當(dāng)前被收藏?cái)?shù)","營(yíng)養(yǎng)液數(shù)","文案","視角","出版狀態(tài)","簽約狀態(tài)")
for i in range(0,17):
worksheet.write(0,i,col[i])
# 3.保存數(shù)據(jù)
# 保存到文件中
def saveData(savepath,datalist,count):
for i in range(0,len(datalist)):
data = datalist[i]
for j in range(0,len(data)):
worksheet.write(count+i+1,j,data[j])
workbook.save(savepath)
if __name__ == "__main__":
main("你的存儲(chǔ)路徑")
print("耗時(shí):", time.time() - t1)
5結(jié)果
? ? ? ? 500頁(yè)每頁(yè)100本小說(shuō),最后爬取出來(lái)46953條數(shù)據(jù)。
6總結(jié)?
? ? ? ? 回憶性文章,其實(shí)過(guò)程中遇到過(guò)很多問(wèn)題和困難,但暫時(shí)只想起這些了。
????????待改善的地方:
????????1)爬取太慢,爬取250頁(yè)花費(fèi)近10個(gè)小時(shí),看網(wǎng)上有多進(jìn)程、多線程可以加快爬蟲(chóng)時(shí)間,之后有時(shí)間當(dāng)學(xué)習(xí)改進(jìn);
????????2)正則表達(dá)式不夠精確,部分詳情頁(yè)爬取出來(lái)不是目的數(shù)據(jù),因?yàn)殄e(cuò)誤的數(shù)據(jù)量不多,后續(xù)數(shù)據(jù)處理采取了直接刪除的辦法,之后可以在爬蟲(chóng)階段嘗試改進(jìn);文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-474890.html
????????3)部分收藏榜頁(yè)整頁(yè)爬取失敗,部分詳情頁(yè)爬取失敗,失敗原因待查。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-474890.html
到了這里,關(guān)于python晉江文學(xué)城數(shù)據(jù)分析(一)——爬蟲(chóng)(BeautifulSoup正則)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!