人民日報語料庫抓取python實現(二)--多執行緒
由於有大量的IO,多執行緒可以提高爬取的效率。出於不同佇列儲存不同url和對於爬蟲進行分工的初衷,這裡實現了兩個佇列shareMonthQueue和shareReportQueue。其中shareMonthQueue儲存所有月份初始url和包含的其他頁面(一個月份有很多page,例:1946年5月包含30個page)。shareReportQueue儲存所有新聞的url。兩個佇列有其專用的爬蟲monthSpider和reportSpider。師兄說:從作業系統的角度來看,兩個佇列是多此一舉,增加程式碼複雜度,並不提高效率。我想了想,師兄說的對。
上程式碼:
#coding:utf-8 #author:zhangyang #date:2015-5-21 #此程式用於爬取人民日報下的資料資源。主頁面需要提取包括1946年到2003年之間所有月份 #次級頁面是各個月份的所有報道 #末級頁面是報道內容 #使用多執行緒提高爬取效率 import urllib2,bs4,os,re from time import clock import threading,Queue #關於bs4解析url的方法可以參看:http://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html starturl="http://rmrbw.info/" shareMonthQueue=Queue.Queue() #儲存月份url的公共佇列 shareReportQueue=Queue.Queue() #c儲存新聞url的公共佇列 _WORK_MONTH_THREAD_NUM=3 #用於處理月份url的爬蟲數量 _WORK_REPORT_THREAD_NUM_=10 #用於處理新聞url的爬蟲數量 totalNum=0 #全域性計數器 mutex=threading.Lock() #互斥鎖 tlist=[]<span style="white-space:pre"> </span>#執行緒列表 t1=clock() t2=clock() t3=clock() t4=clock() class monthSplider(threading.Thread): def __init__(self,name,dicPath = os.getcwd()+os.path.sep+"data"+os.path.sep): threading.Thread.__init__(self) self.name=name self.dicPath=dicPath self.TIMEOUT=10 def run(self): start=clock() end=clock() while True: if shareMonthQueue.empty()==False: start=clock() monthurl=shareMonthQueue.get() try: page=urllib2.urlopen(monthurl).read() soup=bs4.BeautifulSoup(''.join(page),'lxml') except Exception as e: print "loading url error at line 43" print e continue title=soup.find('a','fl') #找到年月的標籤位置 month=title.contents[0] curpath=os.getcwd() #print month.encode('utf8') datapath=self.dicPath+month.encode('gbk') if os.path.exists(datapath)==False: os.mkdir(datapath) #建立好當月資料夾 pages=soup.find('div','pages').contents[-1] totalpage=pages.split(' ')[3].split('/')[1] #得到總頁面數 templist=monthurl.split('=') curpage=templist[-1] curpage=int(curpage.strip()) #得到當前頁面值 #判斷如果curpage小於totalpage,則把curpage+1得到下一個頁面放入shareMonthQueue中 if curpage<totalpage: templist[-1]=str(curpage+1) nexturl='='.join(templist) shareMonthQueue.put(nexturl) #獲取當前頁面所有新聞的url,並把url放入shareReportQueue裡 res=soup.find_all(id=re.compile("a_ajax_")) for item in res: shareReportQueue.put(starturl+item['href']) else: #在shareMonthQueue為空的情況下等待TIMEOUT秒後退出 end=clock() if (end-start)>self.TIMEOUT: break class reportSpider(threading.Thread): def __init__(self,name,dicPath = os.getcwd()+os.path.sep+"data"+os.path.sep): threading.Thread.__init__(self) self.name=name self.dicPath=dicPath self.TIMEOUT=10 def run(self): start=clock() end=clock() while True: if shareReportQueue.empty()==False: start=clock() url=shareReportQueue.get() try: page=urllib2.urlopen(url).read() soup=bs4.BeautifulSoup(''.join(page),'lxml') except Exception as e: print "loading url error at line 93" print e continue month=soup.find('a',href=re.compile('thread.php')).get_text().strip() #解析當前網頁所在年月 month=month.encode('gbk') title=soup.find('h1','fl').get_text() #解析當前網頁的新聞標題 title=title.strip().split(' ')[0] #print title.encode('utf8') cont_div=soup.find('div','tpc_content') cont=cont_div.get_text().strip() #解析當前網頁的新聞內容 title=title.encode('gbk') cont=cont.encode('gbk') try: filename=self.dicPath+month+os.path.sep+title+'.txt' f=open(filename,'w') f.write(cont) except Exception as e: print str(e)+self.name continue global totalNum global mutex if mutex.acquire(1): totalNum+=1 mutex.release() #print self.name+"處理了一個頁面" if totalNum%100==0: global t3,t4 t4=clock() print "已處理了"+str(totalNum)+"條資料,用時"+str(t4-t3)+'s' else: end=clock() if (end-start)>self.TIMEOUT: break def main(): global t1,t2,t3,t4 t1=clock() pape=urllib2.urlopen(starturl) mainsoup=bs4.BeautifulSoup(''.join(pape),'lxml') alist=mainsoup.find_all('a',class_='fnamecolor',limit=10) for item in alist: monthurl=item['href']+'&page=1' shareMonthQueue.put(starturl+monthurl) t2=clock() print "主頁面爬取完成,用時"+str(t2-t1)+'s' for i in xrange(_WORK_REPORT_THREAD_NUM_): if i<_WORK_MONTH_THREAD_NUM: ms=monthSplider('ms'+str(i)) tlist.append(ms) rs=reportSpider('rs'+str(i)) tlist.append(rs) t3=clock() print "爬蟲準備就緒,用時"+str(t3-t2)+'s' for t in tlist: t.start() for t in tlist: t.join() if __name__=="__main__": main()
相關推薦
人民日報語料庫抓取python實現(二)--多執行緒
由於有大量的IO,多執行緒可以提高爬取的效率。出於不同佇列儲存不同url和對於爬蟲進行分工的初衷,這裡實現了兩個佇列shareMonthQueue和shareReportQueue。其中shareMonthQueue儲存所有月份初始url和包含的其他頁面(一個月份有很多pa
Java併發程式設計(二)多執行緒四種實現方式
Java實現多執行緒的方式 Java實現多執行緒的方式有4種: 繼承Thread方法、實現Runnable介面、實現Callable介面並通過FutureTask建立執行緒、使用ExecutorService。 其中,前兩種執行緒執行結果沒有返回值,後兩種是有返回值的。 1、繼承Th
一行 Python 實現並行化 -- 日常多執行緒操作的新思路
春節坐在回家的火車上百無聊賴,偶然看到 Parallelism in one line 這篇在 Hacker News 和 reddit 上都評論過百的文章,順手譯出,enjoy:-) http://www.zhangzhibo.net/2014/02/01/
學習大資料第五天:最小二乘法的Python實現(二)
1.numpy.random.normal numpy.random.normal numpy.random.normal(loc=0.0, scale=1.0, size=None) Draw random samples from a normal (Gaussi
Python高階程式設計(四)多執行緒
Python 多執行緒 多執行緒類似於同時執行多個不同程式,多執行緒執行有如下優點: 使用執行緒可以把佔據長時間的程式中的任務放到後臺去處理。 使用者介面可以更加吸引人,這樣比如使用者點選了一個按鈕去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度 程式的執
Java Socket應用(三)多執行緒實現多客戶端的通訊
伺服器執行緒處理類ServerThread.java : package com.yijia; import java.io.*; import java.net.Socket; /** * 建立時間:2018/10/4 14:59 * 作者: * 郵箱:[ema
python高階(二)——多工(三)協程(3)圖片下載器
import urllib.request import gevent from gevent import monkey monkey.patch_all() def downloader(img_name, img_url): req = urllib.request.urlope
python高階(二)——多工(三)協程(2)
協程 協程,又稱微執行緒,纖程。英文名Coroutine。 協程是啥 協程是python箇中另外一種實現多工的方式,只不過比執行緒更小佔用更小執行單元(理解為需要的資源)。 為啥說它是一個執行單元,因為它自帶CPU上下文。這樣只要在合適的時機, 我們可以把一個協程 切換到另一個協程。 只
python高階(二)——多工(三)協程(1)迭代器、生成器
迭代器 迭代是訪問集合元素的一種方式。迭代器是一個可以記住遍歷的位置的物件。迭代器物件從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。 1. 可迭代物件 我們已經知道可以對list、tuple、str等型別的資料使用for...in...的迴
python高階(二)——多工(二)程序(2)資料夾拷貝器
import os import multiprocessing def copy_file(q, file_name, old_folder_name, new_folder_name): """完成檔案複製""" old_f = open(old_folder_name +
python高階(二)——多工(二)程序(1)
程序以及狀態 1. 程序 程式:例如xxx.py這是程式,是一個靜態的 程序:一個程式執行起來後,程式碼+用到的資源 稱之為程序,它是作業系統分配資源的基本單元。 不僅可以通過執行緒完成多工,程序也是可以的 2. 程序的狀態 工作中,任務數往往大於cpu的核數,即一定有一些任
python高階(二)——多工(一)執行緒(2)多執行緒UDP聊天器
import socket import threading def recv_msg(udp_socket): # 接收資料 while True: recv_data = udp_socket.recvfrom(1024) print(recv
作業系統(Linux)多執行緒--互斥量實現同步
在訊號量中用sem_t結構表示,在互斥量中用pthread_mutexattr_t表示。 使用互斥變數以前,必須首先對它進行初始化,可以把它設定為常量PTHREAD_MUTEX_INITIALIZER(只適合用於靜態分配的互斥量), 也可以用pthread_mutexa
群聊實現(tcp和多執行緒)
服務端程式碼 package com.cyj.tcp.chat2; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import ja
爬蟲記錄(4)——多執行緒爬取圖片並下載
還是繼續前幾篇文章的程式碼。 當我們需要爬取的圖片量級比較大的時候,就需要多執行緒爬取下載了。這裡我們用到forkjoin pool來處理併發。 1、DownloadTask下載任務類 package com.dyw.crawler.util;
python進階(9)多執行緒
# 什麼是執行緒? 執行緒也叫`輕量級程序`,是作業系統能夠進行`運算排程`的`最小`單位,它被包涵在程序之中,是程序中的實際運作單位。執行緒自己不擁有`系統資源`,只擁有一點兒在執行中必不可少的資源,但它可與同屬一個程序的其他執行緒共享程序所擁有的全部資源。一個執行緒可以建立和撤銷另一個執行緒,同一個程序中
1998年人民日報語料庫,詞的最長,最短匹配 提取問題,
由於語料中包括 [中央/n 人民/n 廣播/vn 電臺/n]nt 此類詞問題,可以選擇最長詞提取,也可以選擇最短詞提取 # -*- coding: utf-8 -*- import codecs wordfile=codecs.open("199801.txt
基於Java的網路爬蟲實現抓取網路小說(一)
package novel.spider.impl; import java.util.ArrayList; import java.util.List; import org.apache.http.client.methods.CloseableHttpResponse; import org.apa
八大排序算法python實現(轉)
n) 順序 tails detail 時間 tail 哨兵 插入元素 lang 一、概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。