Это приводит к дублированию результатов, потому что при создании потоков вы вызываете одну и ту же функцию три раза.
t = threading.Thread(target = runner, args = (fname, ))
Когда вы выполняете вышеприведенную строку, аргумент всегда остается fname
, насколько я понимаю, это всегда "ProductLinks.txt"
. Поэтому ваша программа перейдет в runner
, и я вижу, что вы перебираете все строки текста.
Я подозреваю, что то, что вы хотите "распараллелить", это как раз циклическое перемещение по строкам текста? Затем вам нужно написать функцию parse_line
и передать ее в среду потоков.
Я бы также посоветовал вам сохранить значения в формате dict и в конце экспортировать в csv
, потому что я не уверен, что среда open
является поточно-ориентированной.
def parse_line(line, result_dict):
r = requests.get(line)
soup = BeautifulSoup(r.content, 'lxml')
try:
title = soup.find('h1', id='itemTitle').text.trim().encode('utf-8')
price = soup.find('span', itemprop='price').text.trim().encode('utf-8')
result_dict[title] = price
except:
result_dict['No title'] = "No price"
Теперь скажите, что у вас есть список со всеми строками в вашем файле в виде строк. Вы можете добиться этого, выполнив следующее
file_lines = []
with open(fname, 'r') as f:
for line in f:
file_lines.append(line)
Затем вы можете вызвать эту функцию, используя Threading
над списком всех строк в вашем файле
my_dict = {}
for input_line in file_lines:
t = threading.Thread(target = parse_line, args = (input_line, my_dict))
threads.append(t)
t.start()
Наконец, вы можете экспортировать ваш диктет в csv
, используя панд
import pandas as pd
pd.DataFrame(my_dict).to_csv("Data.csv")