日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python多线程爬虫数据顺序_多线程爬取小说时如何保证章节的顺序

發布時間:2025/3/19 python 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python多线程爬虫数据顺序_多线程爬取小说时如何保证章节的顺序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

爬取小說時,以每一個章節為一個線程進行爬取,如果不加以控制的話,保存的時候各個章節之間的順序會亂掉。

當然,這里說的是一本小說保存為單個txt文件,如果以每個章節為一個txt文件,自然不會存在這種情況。

不僅僅是小說,一些其他的數據在多線程爬取時也有類似情況,比如:

漫畫:漫畫其實是由大量圖片組成,一般一本漫畫會保存為一個pdf文件,在此過程要保證圖片的順序。

視頻:現在網絡上的視頻大部分是由多個ts文件拼合,最后保存為一個mp4文件,要保證ts文件的順序。

它們都有一個共同的特點,那就是:爬取目標時有多個鏈接,但保存后卻只有一個文件,且無法在保存完畢后進行二次排序。

單線程時,這一類文件的爬取不會出現任何問題;

多線程時,因為爬取順序的不確定性,導致保存的順序紊亂。

解決方案

問題的根本原因在于:因為爬取和保存的一致性,混亂的爬取順序使得保存順序也變得混亂。

解決方案:將爬取過程和保存過程分離,多線程爬取數據,但按順序保存數據。

比如一本小說,在爬取章節的過程中可以使用多線程,但不要在爬取之后立即保存,等待時機,精準寫入。

那這個時機是什么呢?

可以在爬取章節的過程中,給每個章節一個帶序號的標記,這個序號即小說章節的序號;保存時,從序號0開始保存,記錄這一個序號,再檢測當前爬取的章節中有沒有比記錄的序號剛好大于1的(大于1相當于下一個章節),有就寫入,沒有就等待。

具體過程:

爬取目錄頁,抽取出所有的章節鏈接。

將所有待爬取的鏈接扔到一個隊列里面去,同時給每個鏈接一個標記。

開5個線程,不斷地從隊列里面拿鏈接進行爬取。

單個章節爬取之后,讓爬取這個鏈接的線程阻塞。

申明一個成員變量,表示保存的章節序號,從-1開始

當前線程的鏈接標記是否剛好比章節序號大于1,是就保存,不是就繼續阻塞

因為是從隊列中取數據,就能夠保證這5個章節是還沒有被爬取的前5個章節

具體實現

爬蟲代碼用的python實現,自定義的線程類,這里以http://www.booktxt.net/8_8455/爬取為例。

代碼如下:

importrequestsfrom lxml importetreefrom threading importThreadfrom queue importQueueclassMyThread(Thread):def __init__(self, q):

Thread.__init__(self)

self.q=qdefrun(self):globalindexwhile notself.q.empty():

data=self.q.get()

url= root + ''.join(data[1])

response= requests.get(url, headers=headers)

page=etree.HTML(response.content)

chapter= page.xpath("//h1/text()")

chapter= ''.join(chapter)print("爬取 -> %s" %chapter,index)

content= page.xpath("//div[@id='content']/text()")

content= '\n'.join(content)

content= content.replace("\xa0\xa0\xa0\xa0", "\t")#如果當前標記比保存的小說章節序號大于1,阻塞

while data[0] > index + 1:pass

#剛好大于1時,通過,保存章節

if data[0] == index + 1:print("保存 -> %s" %chapter,index)

f.write('\n' + chapter + '\n')

f.write(content)

index+= 1

if __name__ == '__main__':

root= "http://www.booktxt.net/8_8455/"headers={'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}

index= -1 #章節標記,表示保存的章數

response= requests.get(root, headers=headers)

page=etree.HTML(response.content)

title= ''.join(page.xpath("//h1/text()")) #小說名

print(title)

with open("%s.txt" % title, 'w', encoding='utf8') as f:

f.write(title)#先寫入小說名

hrefs = page.xpath("//div[@id='list']/dl/dt[2]/following-sibling::dd/a/@href")

q=Queue()for i,href inenumerate(hrefs):

q.put((i,href))

ts=[]for i in range(5):

t=MyThread(q)

t.start()

ts.append(t)for t ints:

t.join()

代碼整體上并不復雜,用的也是requests+lxml的經典組合,主要是隊列數據寫入和線程阻塞那里,能夠理解整個也就不難了。

總結

該說的也都說了,最后說一句:

如果是鍛煉技術的話可以多線程爬這玩玩,但如果要寫全網爬蟲,還是寫個單線程吧,尤其是在自己時間足夠充裕的情況下,畢竟人家租個服務器也不容易。

總結

以上是生活随笔為你收集整理的python多线程爬虫数据顺序_多线程爬取小说时如何保证章节的顺序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。