摘要:對之前我的那個(gè)豆瓣的短評的爬蟲,進(jìn)行了一下架構(gòu)性的改動。同時(shí)也添加了多線程的實(shí)現(xiàn)。我的代碼中多線程的核心代碼不多,見下。注意使用多線程時(shí),期間的延時(shí)時(shí)間應(yīng)該設(shè)置的大些,不然會被網(wǎng)站拒絕訪問,這時(shí)你還得去豆瓣認(rèn)證下我真的不是機(jī)器人尷尬。
對之前我的那個(gè)豆瓣的短評的爬蟲,進(jìn)行了一下架構(gòu)性的改動。盡可能實(shí)現(xiàn)了模塊的分離。但是總是感覺不完美。暫時(shí)也沒心情折騰了。
同時(shí)也添加了多線程的實(shí)現(xiàn)。具體過程見下。
改動 獨(dú)立出來的部分:MakeOpener
MakeRes
GetNum
IOFile
GetSoup
main
將所有的代碼都置于函數(shù)之中,顯得干凈了許多。(^__^) 嘻嘻……
使用直接調(diào)用文件入口作為程序的起點(diǎn)if __name__ == "__main__": main()
注意,這一句并不代表如果該if之前有其他直接暴露出來的代碼時(shí),他會首先執(zhí)行。
print("首先執(zhí)行") if __name__ == "__main__": print("次序執(zhí)行") # 輸出如下: # 首先執(zhí)行 # 次序執(zhí)行
該if語句只是代表順序執(zhí)行到這句話時(shí)進(jìn)行判斷調(diào)用者是誰,若是直接運(yùn)行的該文件,則進(jìn)入結(jié)構(gòu),若是其他文件調(diào)用,那就跳過。
多線程這里參考了【Python數(shù)據(jù)分析】Python3多線程并發(fā)網(wǎng)絡(luò)爬蟲-以豆瓣圖書Top,和我的情況較為類似,參考較為容易。
仔細(xì)想想就可以發(fā)現(xiàn),其實(shí)爬10頁(每頁25本),這10頁爬的先后關(guān)系是無所謂的,因?yàn)閷懭氲臅r(shí)候沒有依賴關(guān)系,各寫各的,所以用串行方式爬取是吃虧的。顯然可以用并發(fā)來加快速度,而且由于沒有同步互斥關(guān)系,所以連鎖都不用上。
正如引用博文所說,由于問題的特殊性,我用了與之相似的較為直接的直接分配給各個(gè)線程不同的任務(wù),而避免了線程交互導(dǎo)致的其他問題。
我的代碼中多線程的核心代碼不多,見下。
thread = [] for i in range(0, 10): t = threading.Thread( target=IOFile, args=(soup, opener, file, pagelist[i], step) ) thread.append(t) # 建立線程 for i in range(0, 10): thread[i].start() for i in range(0, 10): thread[i].join()
調(diào)用線程庫threading,向threading.Thread()類中傳入要用線程運(yùn)行的函數(shù)及其參數(shù)。
線程列表依次添加對應(yīng)不同參數(shù)的線程,pagelist[i],step兩個(gè)參數(shù)是關(guān)鍵,我是分別為每個(gè)線程分配了不同的頁面鏈接,這個(gè)地方我想了半天,最終使用了一些數(shù)學(xué)計(jì)算來處理了一下。
同時(shí)也簡單試用了下列表生成式:
pagelist = [x for x in range(0, pagenum, step)]
這個(gè)和下面是一致的:
pagelist = [] for x in range(0, pagenum, step): pagelist.append(x)threading.Thread的幾個(gè)方法
值得參考:多線程
start() 啟動線程
jion([timeout]),依次檢驗(yàn)線程池中的線程是否結(jié)束,沒有結(jié)束就阻塞直到線程結(jié)束,如果結(jié)束則跳轉(zhuǎn)執(zhí)行下一個(gè)線程的join函數(shù)。在程序中,最后join()方法使得當(dāng)所調(diào)用線程都執(zhí)行完畢后,主線程才會執(zhí)行下面的代碼。相當(dāng)于實(shí)現(xiàn)了一個(gè)結(jié)束上的同步。這樣避免了前面的線程結(jié)束任務(wù)時(shí),導(dǎo)致文件關(guān)閉。
注意使用多線程時(shí),期間的延時(shí)時(shí)間應(yīng)該設(shè)置的大些,不然會被網(wǎng)站拒絕訪問,這時(shí)你還得去豆瓣認(rèn)證下"我真的不是機(jī)器人"(尷尬)。我設(shè)置了10s,倒是沒問題,再小些,就會出錯(cuò)了。
完整代碼# -*- coding: utf-8 -*- """ Created on Thu Aug 17 16:31:35 2017 @note: 為了便于閱讀,將模塊的引用就近安置了 @author: lart """ import time import socket import re import threading from urllib import parse from urllib import request from http import cookiejar from bs4 import BeautifulSoup from matplotlib import pyplot from datetime import datetime # 用于生成短評頁面網(wǎng)址的函數(shù) def MakeUrl(start): """make the next page"s url""" url = "https://movie.douban.com/subject/26934346/comments?start=" + str(start) + "&limit=20&sort=new_score&status=P" return url def MakeOpener(): """make the opener of requset""" # 保存cookies便于后續(xù)頁面的保持登陸 cookie = cookiejar.CookieJar() cookie_support = request.HTTPCookieProcessor(cookie) opener = request.build_opener(cookie_support) return opener def MakeRes(url, opener, formdata, headers): """make the response of http""" # 編碼信息,生成請求,打開頁面獲取內(nèi)容 data = parse.urlencode(formdata).encode("utf-8") req = request.Request( url=url, data=data, headers=headers ) response = opener.open(req).read().decode("utf-8") return response def GetNum(soup): """get the number of pages""" # 獲得頁面評論文字 totalnum = soup.select("div.mod-hd h2 span a")[0].get_text()[3:-2] # 計(jì)算出頁數(shù) pagenum = int(totalnum) // 20 print("the number of comments is:" + totalnum, "the number of pages is: " + str(pagenum)) return pagenum def IOFile(soup, opener, file, pagestart, step): """the IO operation of file""" # 循環(huán)爬取內(nèi)容 for item in range(step): start = (pagestart + item) * 20 print("第" + str(pagestart + item) + "頁評論開始爬取") url = MakeUrl(start) # 超時(shí)重連 state = False while not state: try: html = opener.open(url).read().decode("utf-8") state = True except socket.timeout: state = False # 獲得評論內(nèi)容 soup = BeautifulSoup(html, "html.parser") comments = soup.select("div.comment > p") for text in comments: file.write(text.get_text().split()[0] + " ") print(text.get_text()) # 延時(shí)1s time.sleep(10) print("線程采集寫入完畢") def GetSoup(): """get the soup and the opener of url""" main_url = "https://accounts.douban.com/login?source=movie" formdata = { "form_email": "your-email", "form_password": "your-password", "source": "movie", "redir": "https://movie.douban.com/subject/26934346/", "login": "登錄" } headers = { "User-Agent": "Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50", "Connection": "keep-alive" } opener = MakeOpener() response_login = MakeRes(main_url, opener, formdata, headers) soup = BeautifulSoup(response_login, "html.parser") if soup.find("img", id="captcha_image"): print("有驗(yàn)證碼") # 獲取驗(yàn)證碼圖片地址 captchaAddr = soup.find("img", id="captcha_image")["src"] # 匹配驗(yàn)證碼id reCaptchaID = r" 運(yùn)行結(jié)果 效率有提升對應(yīng)的單線程程序在github上。單線程:
可見時(shí)間超過30分鐘。修改后時(shí)間縮短到了11分鐘。
文件截圖 我的項(xiàng)目具體文件和對應(yīng)的結(jié)果截圖我放到了我的github上。
mypython
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/40786.html
摘要:,借鑒之前使用的經(jīng)驗(yàn),嘗試直接使用與發(fā)現(xiàn),豆瓣的短評,最一開始還好,但是在爬取將近十多頁的短評時(shí),會報(bào)出的異常,查詢后得知,應(yīng)該是豆瓣對于游客用戶的限制,需要登錄才可以。爬蟲實(shí)踐戰(zhàn)狼豆瓣影評分析 豆瓣上有著大量的影視劇的評論,所以說,要是想要實(shí)現(xiàn)對廣大人民群眾的觀點(diǎn)的分析,對一部片子的理解,綜合來看大家的評論是很有必要的。而短評作為短小精干的快速評論入口,是值得一談的。 所以先要實(shí)現(xiàn)對...
摘要:用戶就我們這一個(gè)宿舍而其中電影的資源則是選擇來自有大量電影電視劇信息的豆瓣。爬蟲應(yīng)對反爬蟲機(jī)制目前來說豆瓣的反爬蟲機(jī)制算是可以接受。 前言 前段時(shí)間和室友鬧劇荒,于是萌生出一種做個(gè)私人化推薦系統(tǒng)想法。(用戶就我們這一個(gè)宿舍)而其中電影的資源則是選擇來自有大量電影電視劇信息的豆瓣。 目前,電影的信息已經(jīng)抓取完畢,共有11159條JSON格式的數(shù)據(jù),內(nèi)容包括: 題目 時(shí)長 類型 導(dǎo)演 主...
摘要:準(zhǔn)備把豆瓣上對它的影評短評做一個(gè)分析。這樣就得到了最新電影的信息了。例如戰(zhàn)狼的短評網(wǎng)址為其中就是電影的,表示評論的第條評論。如下圖所示好的,至此我們已經(jīng)爬取了豆瓣最近播放電影的評論數(shù)據(jù),接下來就要對數(shù)據(jù)進(jìn)行清洗和詞云顯示了。 簡介 剛接觸python不久,做一個(gè)小項(xiàng)目來練練手。前幾天看了《戰(zhàn)狼2》,發(fā)現(xiàn)它在最新上映的電影里面是排行第一的,如下圖所示。準(zhǔn)備把豆瓣上對它的影評(短評)做...
摘要:本文代碼地址爬取豆瓣電影爬取拉勾網(wǎng)職位信息模擬登陸知乎為什么沒人給我點(diǎn)贊。職位名職位信息運(yùn)行結(jié)果模擬登錄知乎通過開發(fā)者工具,獲取的數(shù)據(jù)。 我開通了公眾號【智能制造專欄】,以后技術(shù)類文章會發(fā)在專欄。用Python寫爬蟲是很方便的,最近看了xlzd.me的文章,他的文章寫的很到位,提供了很好的思路。因?yàn)樗奈恼虏糠执a省略了。下面是基于他的文章的三個(gè)代碼片段:基于Python3,Pytho...
摘要:注意爬豆爬一定要加入選項(xiàng),因?yàn)橹灰馕龅骄W(wǎng)站的有,就會自動進(jìn)行過濾處理,把處理結(jié)果分配到相應(yīng)的類別,但偏偏豆瓣里面的為空不需要分配,所以一定要關(guān)掉這個(gè)選項(xiàng)。 本課只針對python3環(huán)境下的Scrapy版本(即scrapy1.3+) 選取什么網(wǎng)站來爬取呢? 對于歪果人,上手練scrapy爬蟲的網(wǎng)站一般是官方練手網(wǎng)站 http://quotes.toscrape.com 我們中國人,當(dāng)然...
閱讀 1212·2019-08-30 12:44
閱讀 696·2019-08-29 13:03
閱讀 2608·2019-08-28 18:15
閱讀 2467·2019-08-26 10:41
閱讀 3144·2019-08-26 10:28
閱讀 3077·2019-08-23 16:54
閱讀 2051·2019-08-23 15:16
閱讀 876·2019-08-23 14:55