马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
如图,初学者,想多线程写一个爬虫,构思了一个框架,尝试了一下,发现不能运行完整,中途就结束了,请各位大佬劳烦看一下问题在哪里。
代码如下
import threading
import time
from queue import Queue
import requests
t1 = time.time()
url_queue = Queue()
def download():
while not url_queue.empty():
url=url_queue.get()
res = requests.get(url)
print(url,res.status_code,res.encoding)
return res.status_code
# print(res.headers)
urls = ['http://www.038909.xyz', 'http://www.solucky.com.cn',
'http://www.baidu.com', 'http://www.bing.com', 'http://www.cnbeta.com', 'http://16666.com'
]
for url in urls:
url_queue.put(url)
for i in range(3):
t = threading.Thread(target=download)
t.start()
运行结果:
当range(3)时,只跑前三个,后面的url不跑。
/Volumes/DATA/PythonData/venv/bin/python /Volumes/DATA/doc&docx/2.py
http://www.038909.xyz 200 ISO-8859-1
http://www.baidu.com 200 ISO-8859-1
http://www.solucky.com.cn 502 None
从你提供的代码来看,你创建了三个线程来执行 `download` 函数。每个线程在队列中取出一个 URL 进行下载,但是当 `download` 函数返回结果后,线程就结束了。所以你观察到的现象是只有前三个 URL 被处理了。
你可以通过让每个线程处理多个 URL 来解决这个问题。这可以通过在 `download` 函数中添加一个循环来实现。当一个线程处理完一个 URL 后,它将继续处理队列中的下一个 URL,直到队列为空。这里是修改后的代码:
import threading
import time
from queue import Queue
import requests
t1 = time.time()
url_queue = Queue()
def download():
while not url_queue.empty():
url = url_queue.get()
res = requests.get(url)
print(url, res.status_code, res.encoding)
url_queue.task_done() # 需要添加这行,以通知队列此任务已完成
urls = [
'http://www.038909.xyz', 'http://www.solucky.com.cn',
'http://www.baidu.com', 'http://www.bing.com', 'http://www.cnbeta.com', 'http://16666.com'
]
for url in urls:
url_queue.put(url)
threads = [] # 创建一个线程列表,用于保存所有线程
for i in range(3):
t = threading.Thread(target=download)
t.start()
threads.append(t) # 把线程添加到线程列表
# 等待所有任务完成
url_queue.join()
# 等待所有线程结束
for t in threads:
t.join()
t2 = time.time()
print('Total time: ', t2 - t1)
这样修改后,你的代码应该可以正确地处理所有的 URL 了。不过,还有一点需要注意:由于多线程操作不是线程安全的,可能会出现一些意外情况。在实际编写爬虫时,建议使用线程池 (如 `concurrent.futures.ThreadPoolExecutor`) 等更高级的并发工具,以确保程序的稳定性和可扩展性。
|