多线程爬虫



多线程类似于同时执行多个不同程序,多线程运行有如下优点:

  • 使用线程可以把占据长时间的程序中的任务放到后台去处理。

  • 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度

  • 程序的运行速度可能加快

  • 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

Python 提供了多个模块来支持多线程编程,包括 thread、threading 和 Queue 模块等。程序是可以使用 thread 和 threading 模块来创建与管理线程。 thread 模块提供了基本的线程和锁定支持;而 threading 模块提供了更高级别、功能更全面的线程管理。推荐使用更高级别的 threading 模块,而不使用 thread 模块有很多原因:threading 模块更加先进,有更好的线程支持,并且 thread 模块中的一些属性会和 threading 模块有冲突,另一个原因是低级别的 thread 模块拥有的同步原语很少(实际上只有一个),而 threading 模块有很多。再有避免使用 thread 模块的原因是它对于进程何时退出没有控制。当主线程结束时,所有其他线程也都强制结束,不会发出警告或者进行适当的清理。如上所述,至少 threading 模块能够确保重要的子线程在进程退出前结束。

下面会使用传统单线程和多线程进行网页爬虫。


单线程爬虫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import requests
from bs4 import BeautifulSoup
import time


class BooksSpider(object):

def __init__(self, url):
self.url = url

def get_source(self, url):
resp = requests.get(url)
if resp.status_code == 200:
return resp.text
else:
return None

def parse_html(self):
html = self.get_source(self.url)
soup = BeautifulSoup(html, 'lxml')
items = soup.find_all('li', class_='col-xs-6')
for item in items:
title = item.find('h3').get_text()
print(title)

def run(self):
self.parse_html()

def main():

# 构造所有url
base_url = 'http://books.toscrape.com/catalogue/page-{}.html'
url_list = [base_url.format(page) for page in range(1, 51)]

for url in url_list:
p = BooksSpider(url)
p.run()


if __name__ == '__main__':
start = time.time()
main()
print('cost time:%s' % (time.time() - start))

多线程爬虫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import requests
from bs4 import BeautifulSoup
import time
from threading import Thread
from queue import Queue


class BooksSpider(Thread):

def __init__(self, url, q):
super(BooksSpider, self).__init__()
self.url = url
self.q = q

def get_source(self, url):
resp = requests.get(url)
if resp.status_code == 200:
return resp.text
else:
return None

def parse_html(self):
html = self.get_source(self.url)
soup = BeautifulSoup(html, 'lxml')
items = soup.find_all('li', class_='col-xs-6')
for item in items:
title = item.find('h3').get_text()
price = '1'
self.q.put(title)
# print(title)

def run(self):
self.parse_html()

def main():

# 创建队列
q = Queue()

# 构造所有url
base_url = 'http://books.toscrape.com/catalogue/page-{}.html'
url_list = [base_url.format(page) for page in range(1, 51)]

# 保存线程
Thread_list = []

# 创建并启动线程
for url in url_list:
p = BooksSpider(url, q)
p.start()
Thread_list.append(p)

#
for i in Thread_list:
i.join()

while not q.empty():
print(q.get())


if __name__ == '__main__':
start = time.time()
main()
print('cost time:%s' % (time.time() - start))

-------------本文结束感谢您的阅读-------------

本文标题:多线程爬虫

文章作者:Tang

发布时间:2018年12月14日 - 16:12

最后更新:2019年01月20日 - 18:01

原始链接:https://tangx1.com/bookSpdier/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

0%