【问题标题】:How can I merge keys with the same value into a single object?如何将具有相同值的键合并到一个对象中?
【发布时间】:2020-09-18 05:40:50
【问题描述】:

我使用 Parsehub API 以 json 格式抓取以下数据,当我想打印某个国家/地区的信息时,我只能获取第一组数据:'name'、'pop'、' area'、'growth'、'worldPer' 和 'rank' 但我无法获得 'image'。

当我打印整个json文件时,数据都在那里,但是当我尝试用图像值打印一个国家数据时,我得到一个关键错误。

有没有办法通过匹配国家名称来合并这两个对象?

main.py

class Data:
    def __init__(self, api_key, project_token):
        self.api_key = api_key
        self.project_token = project_token
        self.params = {"api_key":api_key}
        self.data = self.get_data()

    def get_data(self):
        r = requests.get(f'https://www.parsehub.com/api/v2/projects/xxxx/last_ready_run/data', params={"api_key": DATA_API_KEY})
        data = json.loads(r.text)
        print(r.text)
        return data

    def data_by_name(self,country):
        data = self.data['country']
        for content in data:
            if content['name'].lower() == country.lower():
                print(content)
                name = content['name']
                pop = content['pop']
                popRank = content['rank']
                growth = content['growth']
                per = content['worldPer']
                area = content['area']
                image = content['image'] #<----- KeyError: 'image'
        return(name,pop,popRank,growth,per,area)

data = Data(DATA_API_KEY,DATA_PROJECT_TOKEN)
data.data_by_name('china')

国家.json

{
 "country": [
  {
   "name": "China",
   "pop": "1,438,862,614",
   "area": "9,706,961 km²",
   "growth": "0.39%",
   "worldPer": "18.47%",
   "rank": "1"
  },
  {
   "name": "China",
   "image": "https://s3.amazonaws.com/images.wpr.com/flag-pages/png250/cn.png"
  }
 ]
}

【问题讨论】:

    标签: python python-3.x web-scraping html-parsing parsehub


    【解决方案1】:

    熊猫可以帮你处理

    import pandas as pd
    
    d = {
     "country": [
      {
       "name": "China",
       "pop": "1,438,862,614",
       "area": "9,706,961 km²",
       "growth": "0.39%",
       "worldPer": "18.47%",
       "rank": "1"
      },
      {
       "name": "China",
       "image": "https://s3.amazonaws.com/images.wpr.com/flag-pages/png250/cn.png"
      }
     ]
    }
    
    df = pd.DataFrame.from_dict(d['country']).groupby('name').first()
    

    输出

                     pop           area growth worldPer rank                                              image
    name
    China  1,438,862,614  9,706,961 km²  0.39%   18.47%    1  https://s3.amazonaws.com/images.wpr.com/flag-p...
    

    【讨论】:

      【解决方案2】:

      最好将每个国家/地区的数据存储在字典中,这样您就不会每次都遍历所有数据。你可以这样做:

      def __init__(self, api_key, project_token):
          ...
          self.countries_data = self.get_countries_data()
      
      ...
      
      def get_countries_data(self):
          countries_data = {}
          for content in self.data["country"]:
              name = content["name"]
              countries_data[name] = {**countries_data.get(name, {}), **content}
          return countries_data
      
      def data_by_name(self, country):
          conuntry_data = self.countries_data[country]
          return country_data["name"], country_data["pop"]...
      

      【讨论】:

        【解决方案3】:

        有(至少)两种方法可以解决这个问题:您可以合并所有具有相同名称的不同条目,例如china,在数据中。或者您可以每次搜索所有国家,并从每个与您的国家匹配的国家中获取所有必要的数据。这是第二个示例,我在其中修改了您的 data_by_name 方法。这样做的好处是,即使您不知道该国家/地区可能出现多少次,它也能正常工作:

        def data_by_name(self,country):
            data = self.data['country']
            my_dict = {}
            for content in data:
                if content['name'].lower() == country.lower():
                    print(content)
                    my_dict.update(content) # This updates your dict with the key/value pairs
            return my_dict     # my_dict will have all the different values, including image
        

        如果你只想要特定的字段,你可以返回那些:

            return (
                my_dict['name'],
                my_dict['pop'],
                my_dict['rank'],
                my_dict['growth'],
                my_dict['worldPer'],
                my_dict['area'],
                my_dict['image']
            )
        

        希望对您有所帮助,祝您编码愉快!

        【讨论】:

          猜你喜欢
          • 2017-09-28
          • 2023-01-09
          • 1970-01-01
          • 1970-01-01
          • 2021-04-09
          • 1970-01-01
          • 2022-11-01
          • 1970-01-01
          • 2018-06-04
          相关资源
          最近更新 更多