Как исправить ошибку «TypeError: объект int не повторяется» в потоке concurrent.futures? - PullRequest
0 голосов
/ 02 мая 2019

Моя цель - очистить некоторые ссылки и использовать потоки, чтобы сделать это быстрее.

Когда я пытаюсь создавать потоки, это вызывает TypeError: 'int' object is not iterable.

Вот наш скрипт:

import requests
import pandas
import json
import concurrent.futures
from from collections import Iterable

# our profiles that we will scrape
profile = ['kaid_329989584305166460858587','kaid_896965538702696832878421','kaid_1016087245179855929335360','kaid_107978685698667673890057','kaid_797178279095652336786972','kaid_1071597544417993409487377','kaid_635504323514339937071278','kaid_415838303653268882671828','kaid_176050803424226087137783']

# lists of the data that we are going to fill up with each profile
total_project_votes=[]

def scraper(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))
    sum_votes=[]
    try:
        data=data.json()
        for item in data['scratchpads']:
            try :
                sum_votes=item['sumVotesIncremented']
            except KeyError:
                pass
        sum_votes=map(int,sum_votes) # change all items of the list in integers
        print(isinstance(sum_votes, Iterable)) #to check if it is an iterable element
        print(isinstance(sum_votes, int)) # to check if it is a int element
        sum_votes=list(sum_votes) # transform into a list
        sum_votes=map(abs,sum_votes) # change all items in absolute value
        sum_votes=list(sum_votes) # transform into a list
        sum_votes=sum(sum_votes) # sum all items in the list
        sum_votes=str(sum_votes) # transform into a string
        total_project_votes=sum_votes
    except json.decoder.JSONDecodeError:
        total_project_votes='NA'
    return total_project_votes

with concurrent.futures.ThreadPoolExecutor(max_workers=2) 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]
        results = future.result()
        # print(results) why printing only one of them and then stops?
        total_project_votes.append(results[0])

# write into a dataframe and print it:
d = {'total_project_votes':total_project_votes}
dataframe = pandas.DataFrame(data=d)
print(dataframe)

Я ожидал получить этот вывод:

total_project_votes
0                   0
1                2353
2                  41
3                   0
4                   0
5                  12
6                5529
7                  NA
8                   2

Но вместо этого я получаю эту ошибку:

TypeError: 'int' object is not iterable

Я действительно не понимаю, что означает эта ошибка.Что не так в моем сценарии?Как я могу решить эту проблему?

Когда я смотрю на Traceback, кажется, что именно отсюда возникает проблема: sum_votes=map(int,sum_votes).

ниже некоторой дополнительной информации

Трассировка:

Traceback (most recent call last):
  File "toz.py", line 91, in <module>
    results = future.result()
  File "C:\Users\*\AppData\Local\Programs\Python\Python37-32\lib\concurrent\futures\_base.py", line 425, in result
    return self.__get_result()
  File "C:\Users\*\AppData\Local\Programs\Python\Python37-32\lib\concurrent\futures\_base.py", line 384, in __get_result
    raise self._exception
  File "C:\Users\*\AppData\Local\Programs\Python\Python37-32\lib\concurrent\futures\thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "my_scrap.py", line 71, in scraper
    sum_votes=map(int,sum_votes) # change all items of the list in integers
TypeError: 'int' object is not iterable

1 Ответ

0 голосов
/ 04 мая 2019

Я нашел свою ошибку:

Я должен был поставить: sum_votes.append(item['sumVotesIncremented']) Вместо: sum_votes=item['sumVotesIncremented'].

Кроме того, потому что у нас есть только один элемент: total_project_votes. Наш кортеж results имеет только один элемент. И это может вызвать некоторые проблемы. Потому что когда мы делаем results[0], это не ведет себя как список. Это не будет показывать весь total_project_votes, но первый символ строки. (Например, «Hello» становится «H»). И если total_project_votes был объектом int вместо строки. Это вызвало бы другую ошибку. Чтобы решить эту проблему, мне нужно добавить еще один объект в кортеж results, а затем, когда вы делаете results[0], он фактически ведет себя как список.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...