【爬蟲】對新筆趣閣小說進行爬取,儲存和下載
阿新 • • 發佈:2020-11-23
以前挺愛在筆趣閣看小說的(老白嫖怪了)
現在學了一點爬蟲技術,就自然而然的想到了爬取筆趣閣的小說
也算鍛鍊一下自己的技術,就以新筆趣閣開始
分析
對每一個小說目錄介面的url還是很容易得到的
如聖墟:http://www.xbiquge.la/13/13959/可以知道,遍歷從1到13,從00001到13959,也可以訪問到部分書的目錄介面,但這還是很浪費時間和麻煩
我呢就以下載一本小說為例:
為了有一定的廣泛性,我用selenium先進行操作,
然後在這裡輸入小說名字,點選搜尋,然後獲得新頁面的原始碼
再用xpath解析,找到搜到第一個小說的名字和url
再對url進行requests.get請求得到小說目錄頁碼的原始碼
再進行解析,得到每一章的url以及名字
把每一章的url和名字以字典的方法存到一個列表裡面
再逐步請求每個url,再解析原始碼,得到文字儲存到電腦裡面
程式碼實現
import os
import time
import requests
from selenium import webdriver
from concurrent.futures import ThreadPoolExecutor
from lxml import etree
#selenium路徑
path='C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe'
head={
"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36"
}
novel_name=input("輸入想要下載的小說名字")
#進行自動化操作對筆趣閣進行訪問
bro=webdriver.Chrome(executable_path=path)
bro.get('http://www.xbiquge.la/')
search_off=bro.find_element_by_id('wd')
search_off.send_keys(novel_name)#輸入小說名字
click_search=bro.find_element_by_id('sss')#找到搜尋的位置
click_search.click()#點選搜尋
time.sleep(5)
page_text=bro.page_source
bro.quit()
#得到訪問頁面的原始碼
tree=etree.HTML(page_text)
novel_name=tree.xpath('//*[@id="checkform"]/table/tbody/tr[2]/td[1]/a/text()')[0]#小說名
url=tree.xpath('//*[@id="checkform"]/table/tbody/tr[2]/td[1]/a/@href')[0]
#訪問小說目錄頁面
response=requests.get(url=url,headers=head)
#因為會存在中文亂碼的情況,所以進行下面操作
response.raise_for_status()
response.encoding=response.apparent_encoding
#再進行xpath解析
tree=response.text
tree=etree.HTML(tree)
actor=tree.xpath('//*[@id="info"]/p[1]/text()')[0]#作者名
#建立資料夾
if not os.path.exists('./小說'):
os.mkdir('./小說')
if not os.path.exists('./小說/'+str(novel_name)):
os.mkdir('./小說/'+str(novel_name))
urls=[]
zhangjies=tree.xpath('//*[@id="list"]/dl/dd')#獲得存放章節資訊的列表
for i in zhangjies:
#把每個章節的url和名字以字典型存放
zhangjie_name=i.xpath('./a/text()')[0]+'.txt'
zhangjie_url='http://www.xbiquge.la'+i.xpath('./a/@href')[0]
dic={
'name':zhangjie_name,
'url' :zhangjie_url
}
urls.append(dic)
def data_get_write(dic):
url=dic['url']
for i in range(20):#因為網站容易崩而出現503頁面,故要多次請求
try:
data_get=requests.get(url=url,headers=head)
data_get.raise_for_status()
data_get.encoding=data_get.apparent_encoding
data_tree=data_get.text
break
except:
print("請求出錯,從新請求")
data_tree=etree.HTML(data_tree)
data_writr=data_tree.xpath('//*[@id="content"]/text()')
with open('./小說/'+str(novel_name)+'/'+dic['name'],'w',encoding='utf-8') as fp:#對小說章節進行持久化儲存
for name in data_writr:
fp.write(name)
print(dic['name'],'下載成功!!!')
#time.sleep(1)
#with ThreadPoolExecutor() as pool:#用程序池訪問,因為網站容易崩,所以效率很低
#pool.map(data_get_write,urls)
for dic in urls:#對每個章節單獨訪問
data_get_write(dic)
time.sleep(1)
到此,算是完成了,中間也有很多問題,比如這個網頁太容易崩了,一不小心就503,也可能是因為沒有反爬蟲的機制,伺服器頂不住了,在此要感謝郭大佬的幫助,用多次迴圈try來解決了這個問題
也能很好的儲存下來。
感覺還是很需要多練習,熟能生巧,出現問題也就能很快解決,當然演算法也很重要的,能夠培養思維,會練習的(