多线程在之前的scrapy里面已经接触过了,就是里面的yiled,开启一个新的线程。但是这是这是基于这个高级框架的,用的时候只知道这是开启了一个新的线程,并不是很清楚到底是怎么执行的。
而在python里面有包
import threading
引入这个包之后就可以写自己的多线程了
写多线程的时候需要注意数据的一直性,比如说俩个线程,一个列表,
线程一二同时开始对一个列表进行操作,线程一删除了列表里的一个元素,而线程二不知道线程一删除了此元素,所以还在对此元素进行操作,这时的操作的不必要的无用的操作。
所以多线程里就有了“锁”,在进行公用数据修改的时候需要上锁,上锁之后就只能自己对这段数据进行操作,而其它线程需要等着此线程操作结束后释放锁,才能对这段数据进行访问。
Lock=threading.Lock()#用锁之前先给实例一个锁的对象
Lock.acquire()#获得锁
Lock.release()#释放锁
使用多线程的时候还可以定义类来使用
class Threading (threading.Thread):#继承多线程的初始类
def __init__(self,name,q):
threading.Thread.__init__(self)#重写构造方法
self.name=name
self.q=q
def run(self):#这个方法顾名思义跑起来的意思
Lock.acquire()
url=self.q.pop_url()
bas=basic(url,self.q)
bas.get_urls()
Lock.release()
bas.get_body()
下面是我用多线程试手。。。跑的我们学院网站上全部网址上的文本内容。。。我们学院网站比较厉害。。。没有跑坏掉
#codind=utf-8
from bs4 import BeautifulSoup
import threading
import re
import json
import codecs
import requests
Lock=threading.Lock()
class basic():
def __init__(self,url,q):
self.url=url
self.q=q
def requests_get(self):
header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}
r=requests.get(self.url,headers=header)
return r
def get_body(self):
try:
page = self.requests_get().text
soup = BeautifulSoup(page, 'html.parser')
body = soup.get_text(strip=True)
dict = {'url': self.url, 'body': body}
f = codecs.open('mg1_1.json', 'a+', 'utf-8')
f_json = json.dumps(dict, ensure_ascii=False)
f.write(f_json + '\n')
f.close()
except:
pass
def get_urls(self):
try:
print 'asdafdfasfsd'
html=self.requests_get().text
soup=BeautifulSoup(html,'html.parser')
urls=soup.find_all('a',href=re.compile('.*html'))
for url in urls:
eurl='http://211.81.208.4'+url['href']
self.q.new_url(eurl)
except:
pass
wait_url = []
com_url = []
class que():
def __init__(self,url):
self.url=url
def new_url(self,url):
if url in wait_url:
return
elif url in com_url:
return
else:
wait_url.append(url)
def pop_url(self):
url=wait_url[0]
del wait_url[0]
com_url.append(url)
return url
class Threading (threading.Thread):
def __init__(self,name,q):
threading.Thread.__init__(self)
self.name=name
self.q=q
def run(self):
Lock.acquire()
url=self.q.pop_url()
bas=basic(url,self.q)
bas.get_urls()
Lock.release()
bas.get_body()
def begain(url):
q=que(url)
bas=basic(url,q)
bas.get_urls()
bas.get_body()
while(wait_url):
threading1=Threading('threading1',q)
threading1.run()
begain('http://211.81.208.4/')