Pytrends реализован только на уровне города для США (и без геокода) - PullRequest
1 голос
/ 12 апреля 2020

Я пробовал pytrends и обнаружил, что interest_by_region=city реализован только для США:

 if self.geo == '': 
     self.interest_by_region_widget['request'][ 
         'resolution'] = resolution 
 elif self.geo == 'US' and resolution in ['DMA', 'CITY', 'REGION']: 
     self.interest_by_region_widget['request'][ 
         'resolution'] = resolution 

Я попытался выяснить, чего не хватает в коде для других стран, но я не могу найти. Я только знаю, основываясь на этом фрагменте кода выше, что он работает только для США. Кроме того, я знаю, что могу указать уровень города в тенденциях Google. Может ли кто-нибудь помочь мне найти, какую часть pyrendnds я должен реализовать?

РЕДАКТИРОВАТЬ:

I implemented the suggestion of @mcskinner (+1) that really makes the things simpler (but I got the same problem of my hack). Now, my code is:

import json

import pandas as pd                        
from pytrends.request import TrendReq

#from request import TrendReq

class MyTrendReq(TrendReq):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def interest_by_region(self, resolution='COUNTRY', inc_low_vol=False,
                           inc_geo_code=False):
        """Request data from Google's Interest by Region section and return a dataframe"""

        # make the request
        region_payload = dict()

        if self.geo == '': 
            self.interest_by_region_widget['request']['resolution'] = resolution 
        elif self.geo == 'US' and resolution in ['DMA', 'CITY', 'REGION']: 
            self.interest_by_region_widget['request']['resolution'] = resolution 
        elif len(self.geo) == 2 and resolution in ['CITY', 'REGION']:
            self.interest_by_region_widget['request']['resolution'] = resolution        

        self.interest_by_region_widget['request'][
            'includeLowSearchVolumeGeos'] = inc_low_vol

        # convert to string as requests will mangle
        region_payload['req'] = json.dumps(
            self.interest_by_region_widget['request'])
        region_payload['token'] = self.interest_by_region_widget['token']
        region_payload['tz'] = self.tz

        # parse returned json
        req_json = self._get_data(
            url=TrendReq.INTEREST_BY_REGION_URL,
            method=TrendReq.GET_METHOD,
            trim_chars=5,
            params=region_payload,
        )
        df = pd.DataFrame(req_json['default']['geoMapData'])
        if (df.empty):
            return df

        # rename the column with the search keyword
        df = df[['geoName', 'geoCode', 'value']].set_index(
            ['geoName']).sort_index()
        # split list columns into seperate ones, remove brackets and split on comma
        result_df = df['value'].apply(lambda x: pd.Series(
            str(x).replace('[', '').replace(']', '').split(',')))
        if inc_geo_code:
            result_df['geoCode'] = df['geoCode']

        # rename each column with its search term
        for idx, kw in enumerate(self.kw_list):
            result_df[kw] = result_df[idx].astype('int')
            del result_df[idx]

        return result_df
#import pytrends
if __name__=="__main__":
    pytrend = MyTrendReq()
    pytrend.build_payload(kw_list=['BMW'],geo='BR',timeframe='2019-03-01 2020-03-02')
   # df = pytrend.interest_by_region(resolution='REGION', inc_low_vol=True, inc_geo_code=True)    
    df = pytrend.interest_by_region(resolution='CITY', inc_low_vol=True, inc_geo_code=True)

Я получил следующую ошибку (кажется, что-то не хватает, но я могу вручную выполнить этот вид поиска в гугл трендах):

runfile('/home/daniel/Documents/caju/testingPytrendsStackoverflow.py', wdir='/home/daniel/Documents/caju')
Traceback (most recent call last):

  File "<ipython-input-8-3a8c4f9b3a66>", line 1, in <module>
    runfile('/home/daniel/Documents/caju/testingPytrendsStackoverflow.py', wdir='/home/daniel/Documents/caju')

  File "/usr/lib/python3/dist-packages/spyder/utils/site/sitecustomize.py", line 705, in runfile
    execfile(filename, namespace)

  File "/usr/lib/python3/dist-packages/spyder/utils/site/sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "/home/daniel/Documents/caju/testingPytrendsStackoverflow.py", line 72, in <module>
    df = pytrend.interest_by_region(resolution='CITY', inc_low_vol=True, inc_geo_code=True)

  File "/home/daniel/Documents/caju/testingPytrendsStackoverflow.py", line 53, in interest_by_region
    df = df[['geoName', 'geoCode', 'value']].set_index(

  File "/home/daniel/.local/lib/python3.6/site-packages/pandas/core/frame.py", line 2986, in __getitem__
    indexer = self.loc._convert_to_indexer(key, axis=1, raise_missing=True)

  File "/home/daniel/.local/lib/python3.6/site-packages/pandas/core/indexing.py", line 1285, in _convert_to_indexer
    return self._get_listlike_indexer(obj, axis, **kwargs)[1]

  File "/home/daniel/.local/lib/python3.6/site-packages/pandas/core/indexing.py", line 1092, in _get_listlike_indexer
    keyarr, indexer, o._get_axis_number(axis), raise_missing=raise_missing

  File "/home/daniel/.local/lib/python3.6/site-packages/pandas/core/indexing.py", line 1185, in _validate_read_indexer
    raise KeyError("{} not in index".format(not_found))

KeyError: "['geoCode'] not in index"

Если я заменю в своем коде

df = pytrend.interest_by_region(resolution='CITY', inc_low_vol=True, inc_geo_code=True)

на

   # df = pytrend.interest_by_region(resolution='REGION', inc_low_vol=True, inc_geo_code=True)    

Это работает.

РЕДАКТИРОВАТЬ 2 : @mcskinner правильно. Если я сделаю inc_geo_code=False и прокомментирую

# df = df [['geoName', 'geoCode', 'value']]. Set_index (# ['geoName']). Sort_index ()

Это работает, но я теряю информацию о городе:

     BMW
0    100
1     90
2     88
3     88
4     84
..   ...
105   43
106   43
107   42
108   42
109   38

Суть в том, где я должен включить недостающую информацию о геокоде для Бразилии?

1 Ответ

2 голосов
/ 14 апреля 2020

Сразу после кода, который вы указали, в рамках того же ветвления if / elif вы можете добавить дополнительную ветвь для всех неглобальных и неамериканских регионов.

if self.geo == '': 
    self.interest_by_region_widget['request']['resolution'] = resolution 
elif self.geo == 'US' and resolution in ['DMA', 'CITY', 'REGION']: 
    self.interest_by_region_widget['request']['resolution'] = resolution 
elif len(self.geo) == 2 and resolution in ['CITY', 'REGION']:
    self.interest_by_region_widget['request']['resolution'] = resolution

Условие длины 2 - это хакерство для определения стран. Вы также можете избавиться от условия if и просто всегда пытаться использовать resolution.

self.interest_by_region_widget['request']['resolution'] = resolution

Некоторые комбинации теперь недопустимы (разбивка по методу REGION), и Google Trends не будет работать для те. Вам все равно нужно быть осторожным, обрабатывая их или отправляя только допустимые комбинации, но это даст вам свободу делать это.

Обратите внимание, что все они требуют изменения кода библиотеки. Чтобы сделать это самостоятельно, вы захотите создать свой собственный подкласс TrendReq и переопределить метод Interest_by_region своей собственной измененной копией.

class MyTrendReq(TrendReq):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def interest_by_region(self, resolution='COUNTRY', inc_low_vol=False,
                           inc_geo_code=False):
       # Your modified copy goes here.
...