刚刚学习多线程的时候感觉挺复杂的,但是任何事物的学习都是由简入深,参考廖雪峰大大的文档,大致了解了线程,然后看过一些实战项目,先写的是简单的多线程爬虫。
本次主要拿我第一次学python爬虫时的项目来实践。即爬取百度头像吧。
主线程爬取图片地址,工作线程则负责下载头像。
import time, threading
from lxml import etree
import requests
import re
import queue
#正则主要用于匹配图片
def zhengze(patt,htm):
hh=re.compile(patt)
ll=re.findall(hh,htm)
return ll
#初始链接是头像吧首页,之后是爬取各个帖子
def get_url():
url=r'http://tieba.baidu.com/f?ie=utf-8&kw=%E5%A4%B4%E5%83%8F&fr=search'
html=requests.get(url).content.decode('utf-8')
select=etree.HTML(html)
xp='//*[@id="thread_list"]/li/div/div[2]/div[1]/div[1]/a/@href'
url_list=select.xpath(xp)
#print(url_list)
url_list=map(lambda x:'http://tieba.baidu.com'+x,url_list)
return list(url_list)
#解析网页,提取图片地址放入队列中
def get_down():
#lock = threading.Lock()
global que
url_list=get_url()
print ('start crawl')
for url in url_list:
html=requests.get(url).content.decode('utf-8')
patt='src="(http://imgsrc.baidu.com.+?.jpg)"'
down_list=zhengze(patt,html)
if down_list!=[]:
for e in down_list:
que.put(e)
def down_load(url,name):
jpg=requests.get(url).content
path=r'G:\p\threading_test\img4\\'+name
open(path, 'wb').write(jpg)
print (path)
#工作线程的下载函数,由于是下载,各变量不冲突,不存在线程锁的问题
def run_down():
global que
while True:
if not que.empty():
i=que.get()
name=i[-10:]
down_load(i,name)
else:
print ('end')
break
if __name__ == '__main__':
que=queue.Queue()
quequ=get_url()
t1 = threading.Thread(target=get_down)
t1.start()
time.sleep(8)
print('start down_load')
for i in range(3):
t2 = threading.Thread(target=run_down)
t2.start()