【发布时间】:2021-03-29 12:08:41
【问题描述】:
我正在使用多线程访问从 csv 读取的链接,奇怪的是,不管 max-workers 是什么,甚至当我删除多线程部分时,代码运行的 url 数量也比列表中的任意少。我打印列表以验证计数。例如,如果列表有 5000 个 url,则代码在 4084 处停止,如果链接为 13,000,它将在 9200 处停止,即使只有 130 个链接,它也会在 80 处停止。我在这里做错了什么?
import requests
import xlrd
import concurrent.futures
from bs4 import BeautifulSoup
import csv
header_added = False
file_location = "Urls.xlsx"
workbook = xlrd.open_workbook(file_location)
sheet = workbook.sheet_by_index(0)
all_links = []
for row in range(1, 11000):
all_links.append(sheet.cell_value(row,0))
print(len(all_links))
i = 0
def get_solution(url):
global header_added, i
page = requests.get(url).text
soup = BeautifulSoup(page, 'html.parser')
ques_div = soup.find('p', class_='header-description')
ques = ques_div.find('span').text
ans_divs = soup.findAll('div', class_='puzzle-solution')
ans = ans_divs[0].text
print("Solution ", i)
i += 1
dict1 ={"Words": ques, "Solution": ans}
with open('Results10k.csv', 'a+', encoding='utf-8') as f:
w = csv.DictWriter(f, dict1.keys())
if not header_added:
w.writeheader()
header_added = True
w.writerow(dict1)
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
result = executor.map(get_solution, all_links)
【问题讨论】:
-
这可能不是问题,但所有工作人员都写入同一个文件。我不确定 open() 是否是线程安全的。如果 open() 不是线程安全的,您可以添加互斥锁或写入单个文件并稍后加入它们。
-
@user_na 那将是数千个文件,有什么办法吗?
-
但这种情况发生了,即使我删除了多线程并在
for循环中运行它,就像一个简单的循环一样。 -
可能是某些 URL 的 get_solution() 崩溃。您可以在函数主体中添加 try/except 并将所有崩溃的 URL 写入不同的文件。如果这是问题,则数字加起来应该是总数
-
max_workers=600听起来是个糟糕的主意,顺便说一句,如果你没有 600 个内核可用的话。
标签: python multithreading list web-scraping