Попробуйте что-нибудь подобное? Вместо добавления ссылок и последующего добавления к проектам после некоторого времени выполнения кода, добавление их последовательно должно решить проблему. Но я думаю о лучшем методе атм ...
d = {'link' : [], 'projects' : []}
############### SCRAPING PART ###############
# my scraping function that we are going to use for each item in profile
def scraper (kaid):
link = 'https://www.khanacademy.org/profile/{}'.format(kaid)
data = requests.get('https://www.khanacademy.org/api/internal/user/scratchpads?casing=camel&kaid={}&sort=1&page=0&limit=40000&subject=all&lang=en&_=190425-1456-9243a2c09af3_1556290764747'.format(kaid))
try:
data=data.json()
projects = str(len(data['scratchpads']))
except json.decoder.JSONDecodeError:
projects ='NA'
d['link'].append(link)
d['projects'].append(projects)
Другое решение (не совсем)
Или, что еще лучше, вернуть и ссылку, и проекты в конце выполнения потока, а затем добавить их затем ... (Это я не уверен, будет ли это работать)
def scraper (kaid):
link = 'https://www.khanacademy.org/profile/{}'.format(kaid)
data = requests.get('https://www.khanacademy.org/api/internal/user/scratchpads?casing=camel&kaid={}&sort=1&page=0&limit=40000&subject=all&lang=en&_=190425-1456-9243a2c09af3_1556290764747'.format(kaid))
try:
data=data.json()
projects = str(len(data['scratchpads']))
except json.decoder.JSONDecodeError:
projects = 'NA'
return link, projects
# the threading part
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
future_kaid = {executor.submit(scraper, kaid): kaid for kaid in profile}
for future in concurrent.futures.as_completed(future_kaid):
kaid = future_kaid[future]
data = future.result()
link.append(data[0])
projects.append(data[1])
Я бы сказал, что второе является лучшим решением, так как оно ожидает выполнения всех потоков перед обработкой всех данных в DataFrame. С первым из них все еще существует вероятность того, что может произойти рассогласование во времени (однако они невероятно малы, поскольку мы говорим лишь о разнице в тактовой частоте гигагерца, но просто для полного устранения этого шанса второй вариант лучше).