目錄
- 一、引言
- 二、關(guān)于相關(guān)訪問(wèn)請(qǐng)求及應(yīng)答報(bào)文
- 2.1、百度搜索請(qǐng)求
- 2.2、百度返回搜索結(jié)果
- 2.3、小說(shuō)網(wǎng)站關(guān)于最新更新的展現(xiàn)及html報(bào)文格式
- 三、實(shí)現(xiàn)思路及代碼
- 3.1、根據(jù)url獲取網(wǎng)站名
- 3.2、根據(jù)百度返回搜索結(jié)果地址打開(kāi)網(wǎng)站獲取小說(shuō)信息
- 3.3、獲取小說(shuō)網(wǎng)頁(yè)絕對(duì)url地址
- 3.4、計(jì)算排序權(quán)重
- 3.5、進(jìn)行百度搜索并解析搜索結(jié)果訪問(wèn)小說(shuō)網(wǎng)站最新更新
- 四、搜索案例
- 五、小結(jié)
一、引言
這個(gè)五一假期自駕回老家鄉(xiāng)下,家里沒(méi)裝寬帶,用手機(jī)熱點(diǎn)方式訪問(wèn)網(wǎng)絡(luò)。這次回去感覺(jué)4G信號(hào)沒(méi)有以前好,通過(guò)百度查找小說(shuō)最新更新并打開(kāi)小說(shuō)網(wǎng)站很慢,有時(shí)要打開(kāi)好多個(gè)網(wǎng)頁(yè)才能找到可以正常打開(kāi)的最新更新。為了躲懶,老猿決定利用Python爬蟲(chóng)知識(shí),寫(xiě)個(gè)簡(jiǎn)單應(yīng)用自己查找小說(shuō)最新更新并訪問(wèn)最快的網(wǎng)站,花了點(diǎn)時(shí)間研究了一下相關(guān)報(bào)文,經(jīng)過(guò)近一天時(shí)間研究和編寫(xiě),終于搞定,下面就來(lái)介紹一下整個(gè)過(guò)程。
二、關(guān)于相關(guān)訪問(wèn)請(qǐng)求及應(yīng)答報(bào)文
2.1、百度搜索請(qǐng)求
我們通過(guò)百度網(wǎng)頁(yè)的搜索框進(jìn)行搜索時(shí),提交的url請(qǐng)求是這樣的:
https://www.baidu.com/s?wd=搜索詞pn=10rn=50
請(qǐng)求的url為https://www.baidu.com/s
,帶三個(gè)參數(shù):
- wd:搜索的關(guān)鍵詞
- pn:當(dāng)前需要顯示搜索結(jié)果記錄在總搜索結(jié)果的序號(hào),如總搜索有300條記錄滿足要求,現(xiàn)在要求顯示第130條記錄,則pn參數(shù)值設(shè)為130即可
- rn:每頁(yè)顯示記錄數(shù),缺省為10條,可以自行設(shè)定,但如果設(shè)定超過(guò)50,則會(huì)強(qiáng)制顯示為每頁(yè)10條。
2.2、百度返回搜索結(jié)果
百度返回的搜索結(jié)果有多種方式確定,老猿認(rèn)為如下方式最簡(jiǎn)單:
以搜索小說(shuō)《青萍》為例來(lái)看其中的一個(gè)返回記錄:
h3 class="t">a data-click="{
'F':'778317EA',
'F1':'9D73F1E4',
'F2':'4CA6DE6B',
'F3':'54E5243F',
'T':'1620130755',
'y':'FE7FF57A'}"
rel="external nofollow" target="_blank">
em>青萍/em>最新章節(jié),em>青萍/em>免費(fèi)閱讀 - 大神小說(shuō)網(wǎng)/a>
/h3>
整個(gè)搜索返回的結(jié)果在一個(gè)h3的標(biāo)簽內(nèi),返回的搜索結(jié)果對(duì)應(yīng)url在a標(biāo)簽內(nèi),具體url由href來(lái)指定。這里返回的url實(shí)際上是一個(gè)百度重定向的地址,可以通過(guò)打開(kāi)該url訪問(wèn)對(duì)應(yīng)網(wǎng)站,并通過(guò)返回響應(yīng)消息獲取真正網(wǎng)站的URL。
2.3、小說(shuō)網(wǎng)站關(guān)于最新更新的展現(xiàn)及html報(bào)文格式
根據(jù)老猿分析,約占30%的小說(shuō)網(wǎng)站關(guān)于最新更新章節(jié)的展現(xiàn)類(lèi)似如下:
首先有類(lèi)似“最新章節(jié)”或“最新更新”或“最近更新”等類(lèi)似提示詞,在該提示詞后是顯示最新章節(jié)的章節(jié)序號(hào)及章節(jié)名的一個(gè)鏈接,對(duì)應(yīng)的報(bào)文類(lèi)似如下:
p>最新章節(jié):a href="/book/12/12938/358787.html" rel="external nofollow" target="_blank">第729章 就是給你們看看的/a>/p>
這個(gè)報(bào)文的特點(diǎn)是:
“最新章節(jié)”的文本信息與小說(shuō)最新章節(jié)的鏈接在同一個(gè)父標(biāo)簽內(nèi)。另外需要說(shuō)明的是返回的章節(jié)url并不是絕對(duì)地址,而是小說(shuō)網(wǎng)站的相對(duì)地址。
老猿對(duì)搜索小說(shuō)查找最新章節(jié)都是基于以上格式的,因此實(shí)際上程序最終獲取的小說(shuō)網(wǎng)站只占了整個(gè)搜索結(jié)果的30%左右,不過(guò)對(duì)于看小說(shuō)來(lái)說(shuō)已經(jīng)足夠了。
三、實(shí)現(xiàn)思路及代碼
3.1、根據(jù)url獲取網(wǎng)站名
def getHostName(url):
httpPost = url[10:]
hostName = url[:10]+httpPost.split('/')[0]
return hostName
3.2、根據(jù)百度返回搜索結(jié)果地址打開(kāi)網(wǎng)站獲取小說(shuō)信息
基于2.3部分介紹的小說(shuō)網(wǎng)站返回內(nèi)容,我們來(lái)根據(jù)百度返回搜索結(jié)果的URL來(lái)打開(kāi)對(duì)應(yīng)小說(shuō)網(wǎng)站,并計(jì)算從請(qǐng)求發(fā)起到響應(yīng)返回的時(shí)間:
def getNoteInfo(url):
"""
打開(kāi)指定小說(shuō)網(wǎng)頁(yè)URL獲取最新章節(jié)信息
url:百度搜索結(jié)果指定的搜索匹配記錄的url
返回該URL對(duì)應(yīng)的章節(jié)ID、打開(kāi)耗時(shí)、網(wǎng)站真正URL、網(wǎng)站主機(jī)名、章節(jié)相對(duì)url、章節(jié)名
"""
head = mkhead()
start = time.time_ns()
req = urllib.request.Request(url=url, headers=head)
try:
resp = urllib.request.urlopen(req,timeout=2)
#根據(jù)響應(yīng)頭獲取真正的網(wǎng)頁(yè)URL對(duì)應(yīng)的網(wǎng)站名
hostName = getHostName(resp.url)
text = resp.read()
#網(wǎng)頁(yè)編碼有2種:utf-8和GBK
pageText = text.decode('utf-8')
except UnicodeDecodeError:
pageText = text.decode('GBK')
except Exception as e:
errInf = f"打開(kāi)網(wǎng)站 {url} 失敗,異常原因:\n{e}\n" + '\n' + traceback.format_exc() + '\n'
logPag(errInf, False)
return None
#最新章節(jié)的HTML報(bào)文類(lèi)似: 'p>最新章節(jié):a href="/html/107018/122306672.html" rel="external nofollow" >第672章 天之關(guān)梁/a>/p>'
end = time.time_ns()
soup = BeautifulSoup(pageText, 'lxml')
# 根據(jù)最新章節(jié)的提示信息搜索最新章節(jié)
result = soup.find_all(string=re.compile(r'最新更新[::]|最新章節(jié)[::]|最近更新[::]|最新[::]'))
found = False
for rec in result:
recP = rec.parent
pa = recP.a
matchs = re.match(r'(?:最新更新|最新章節(jié)|最近更新|最新)[::]第(.+)章(.+)', recP.text)
if not matchs:return None
groups = matchs.groups()
if matchs and pa is not None:
found = True
chapter = toInt(groups[0]) #章節(jié)序號(hào)
chapterName = groups[1] #章節(jié)名
chaperUrl = pa.attrs['href'] #章節(jié)相對(duì)URL
break
if not found:
return None
cost = (end - start) / 1000000 #網(wǎng)頁(yè)打開(kāi)耗時(shí)計(jì)算
return (chapter,cost,resp.url,hostName,chaperUrl,chapterName)
注意:由于不同網(wǎng)站訪問(wèn)響應(yīng)情況不一樣,因此在打開(kāi)網(wǎng)頁(yè)時(shí)設(shè)定超時(shí)是很有必要的,這樣可以避免訪問(wèn)緩慢的網(wǎng)站耽誤整體訪問(wèn)時(shí)間。
3.3、獲取小說(shuō)網(wǎng)頁(yè)絕對(duì)url地址
將返回信息中相對(duì)url和網(wǎng)站名結(jié)合拼湊網(wǎng)頁(yè)的絕對(duì)url地址:
def getChapterUrl(noteInf):
chapter, cost, url, hostName, chaperUrl, chapterName = noteInf
if chaperUrl.strip().startswith('http'):return chaperUrl
elif chaperUrl.strip().startswith('/'):return hostName.strip()+chaperUrl.strip()
else:return hostName.strip()+'/'+chaperUrl.strip()
3.4、計(jì)算排序權(quán)重
根據(jù)搜索小說(shuō)網(wǎng)頁(yè)訪問(wèn)的信息計(jì)算排序權(quán)重,確保最新章節(jié)排在最前,相同章節(jié)訪問(wèn)速度最快網(wǎng)站排在最前。
def noteWeight(n):
#入?yún)為小說(shuō)信息元組: chapter, cost, url, hostName, chaperUrl, chapterName
ch,co = n[:2]
w = ch * 100000 + min(99999, 100000 / co)
return w
3.5、進(jìn)行百度搜索并解析搜索結(jié)果訪問(wèn)小說(shuō)網(wǎng)站最新更新
根據(jù)搜索詞在百度執(zhí)行搜索,并取最新章節(jié)且訪問(wèn)速度最快的前5個(gè)網(wǎng)站url進(jìn)行輸出:
def BDSearchUsingChrome(inputword,maxCount=150):
"""
輸出相關(guān)搜索結(jié)果中具有最新章節(jié)且訪問(wèn)速度最快的前5個(gè)網(wǎng)站url
:param word: 搜索關(guān)鍵詞,如小說(shuō)名、小說(shuō)名+作者名等
:param maxCount: 最多處理的搜索記錄數(shù)
:return: None
"""
#百度請(qǐng)求url類(lèi)似:https://www.baidu.com/s?wd=青萍pn=10rn=50
rn = 50 #每頁(yè)50條記錄
#構(gòu)建請(qǐng)求頭模擬本機(jī)谷歌瀏覽器訪問(wèn)百度網(wǎng)頁(yè)
head = mkheadByHostForChrome('baidu.com')
word = urllib.parse.quote(inputword)
urlPagePre = 'https://www.baidu.com/s?wd='+word+'rn=50'
pageCount = int(0.999+maxCount/rn)
validNoteInf = []
seq = 0
logPag("開(kāi)始執(zhí)行搜索...")
for page in range(pageCount):
pn = rn*page
urlPage = urlPagePre+str(pn)
pageReq = urllib.request.Request(url=urlPage, headers=head)
pageResp = urllib.request.urlopen(pageReq,timeout=2)
pageText = pageResp.read().decode()
if pageResp.status == 200:
soup = BeautifulSoup(pageText,'lxml')
links = soup.select('h3.t a[href^="http://www.baidu.com/link?url="]')
for l in links:
noteInf = getNoteInfo(l.attrs['href'])
seq += 1
if noteInf is None:
#print(seq,'、',l.attrs['href'],None)
logPag(f"{seq}、{l.attrs['href']}:查找最新章節(jié)失敗,忽略",True)
else:
logPag(f"{seq}、返回小說(shuō)信息: {noteInf}",True)
#chapter,cost,url,hostName,chaperUrl,chapterName = noteInf
validNoteInf.append(noteInf)
validNoteInf.sort(key=noteWeight,reverse=True)
print(f"小說(shuō): {inputword} 最新更新訪問(wèn)最快的5個(gè)網(wǎng)站是:")
for l in validNoteInf[:5]:#輸出相關(guān)搜索結(jié)果中具有最新章節(jié)且訪問(wèn)速度最快的前5個(gè)網(wǎng)站url
print(f"{validNoteInf.index(l)+1}、第{l[0]}章 {l[-1]} {getChapterUrl(l)} ,網(wǎng)頁(yè)打開(kāi)耗時(shí) {l[1]} 毫秒")
input("按回車(chē)鍵退出!")
四、搜索案例
以搜索月關(guān)大大的青萍作為案例,執(zhí)行搜索的語(yǔ)句為:
BDSearchUsingChrome('青萍月關(guān)',150)
執(zhí)行結(jié)果:
小說(shuō): 青萍月關(guān) 最新更新訪問(wèn)最快的5個(gè)網(wǎng)站是:
1、第688章 東邊日出西邊雨 http://www.huaxiaci.com/41620/37631250.html ,網(wǎng)頁(yè)打開(kāi)耗時(shí) 262.0 毫秒
2、第688章 東邊日出西邊雨 http://www.huaxiaci.com/41620/37631250.html ,網(wǎng)頁(yè)打開(kāi)耗時(shí) 278.0 毫秒
3、第688章 東邊日出西邊雨 http://www.huaxiaci.com/41620/37631250.html ,網(wǎng)頁(yè)打開(kāi)耗時(shí) 345.5 毫秒
4、第688章 東邊日出西邊雨 https://www.24kwx.com/book/9/9202/8889236.html ,網(wǎng)頁(yè)打開(kāi)耗時(shí) 774.0 毫秒
5、第688章 東邊日出西邊雨 https://www.27kk.net/9526/2658932.html ,網(wǎng)頁(yè)打開(kāi)耗時(shí) 800.5 毫秒
按回車(chē)鍵退出!
五、小結(jié)
本文介紹了使用Python搜索指定小說(shuō)最新更新章節(jié)以及訪問(wèn)最快網(wǎng)站的實(shí)現(xiàn)思想和關(guān)鍵應(yīng)用代碼,實(shí)現(xiàn)自動(dòng)搜索小說(shuō)最新更新章節(jié)以及獲取訪問(wèn)最快的網(wǎng)站。以上的實(shí)現(xiàn)由于已經(jīng)獲取最新章節(jié)的鏈接,再稍微改進(jìn),就可以直接將最新章節(jié)下載到本地觀看。
到此這篇關(guān)于Python爬蟲(chóng)之爬取最新更新的小說(shuō)網(wǎng)站的文章就介紹到這了,更多相關(guān)Python爬取最新更新的小說(shuō)網(wǎng)站內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- python使用XPath解析數(shù)據(jù)爬取起點(diǎn)小說(shuō)網(wǎng)數(shù)據(jù)
- python爬蟲(chóng)之爬取筆趣閣小說(shuō)
- python爬取晉江文學(xué)城小說(shuō)評(píng)論(情緒分析)
- Python爬蟲(chóng)入門(mén)教程02之筆趣閣小說(shuō)爬取
- python 爬取小說(shuō)并下載的示例
- python爬取”頂點(diǎn)小說(shuō)網(wǎng)“《純陽(yáng)劍尊》的示例代碼
- Python scrapy爬取小說(shuō)代碼案例詳解
- Python爬取365好書(shū)中小說(shuō)代碼實(shí)例
- python爬蟲(chóng)爬取筆趣網(wǎng)小說(shuō)網(wǎng)站過(guò)程圖解
- Python實(shí)現(xiàn)的爬取小說(shuō)爬蟲(chóng)功能示例
- Python制作爬蟲(chóng)采集小說(shuō)
- python 爬取國(guó)內(nèi)小說(shuō)網(wǎng)站