我正在使用Beautiful Soup遍历一些HTML div:
for div in soup.findAll('a', {'class': 'result'}):
adLink = div.a.get('href')
adInfo= {
u'adLink':adLink,
u'adThumbImg':...some code...,
u'adCounty':...some code...
}
adFullInfo = getFullAdInfo(adLink)
adInfo.update(adFullInfo)
ads_CarsURL = pd.DataFrame(data=adInfo) #Create pandas DF
getFullAdInfo
是函数
def getFullAdInfo {
...some code...
}
它返回的字典看起来像这样:
{'adID': '2027007',
'adTitle': 'Ford 750 Special',
'adDatePublished': '20.11.2009',
'adTimePublished': '14:23',
'adViewed': '102',
'carPriceEUR': '600',
'carManufacturer': 'Ford'}
因此,在每次迭代中,我都从adInfo
字典和adFullInfo
函数获取值,该函数返回另一个dict并将它们合并,这样我就可以得到单个字典记录。
想法最终是创建熊猫数据框。
我得到的错误是:
ValueError: arrays must all be same length
我不知道为什么,所以当我最初为每个字典键定义所有变量,并为它们分配空字符串时,像adID=""
一样,以防丢失。
答案 0 :(得分:3)
获得完整的广告后,将其转换为1行数据框,然后将其附加到最终数据框。这样可以解决长度不匹配的问题,也可以解决广告中没有其他可用数据的问题。您必须弄清楚逻辑,因为您没有提供要测试的那部分代码。下面是我意思的简短示例:
import pandas as pd
data1 = {'adID': '2027007',
'adTitle': 'Ford 750 Special',
'adDatePublished': '20.11.2009',
'adTimePublished': '14:23',
'adViewed': '102',
'carPriceEUR': '600',
'carManufacturer': 'Ford'}
data2 = {'adID': '20555',
'adTitle': 'Honda',
'adTimePublished': '11:23',
'adViewed': '2',
'carManufacturer': 'Honda'}
# Initialize empty dataframe
final_df = pd.DataFrame()
# Iterate through your dictionaries, convert to 1 row dataframe and append it to your final dataframe
for data in [data1, data2]:
temp_df = pd.DataFrame(data, index=[0])
final_df = final_df.append(temp_df, sort=True).reset_index(drop=True)
具体随您提供的信息,它类似于:
ads_CarsURL = pd.DataFrame()
for div in soup.findAll('a', {'class': 'result'}):
adLink = div.a.get('href')
adInfo= {
u'adLink':adLink,
u'adThumbImg':...some code...,
u'adCounty':...some code...
}
adFullInfo = getFullAdInfo(adLink)
adInfo.update(adFullInfo)
temp_df = pd.DataFrame(adInfo, index=[0])
ads_CarsURL = final_df.append(temp_df, sort=True).reset_index(drop=True)
输出:
print (final_df.to_string())
adDatePublished adID adTimePublished adTitle adViewed carManufacturer carPriceEUR
0 20.11.2009 2027007 14:23 Ford 750 Special 102 Ford 600
1 NaN 20555 11:23 Honda 2 Honda NaN
答案 1 :(得分:0)
尝试了各种选择,这是产生最佳结果的原因:
我已将adFull = {**adBasicInfo,**adOtherInfo}
的字典正确合并,并在每次迭代中将它们附加到adFullList
列表中。
之后,我可以从adFullList
列表中成功创建熊猫数据框。
其他解决方案无效,因为第二个字典具有某些值的元素列表类型。他们看起来像这样:
adFullDF.iloc[2]['carSafety']
给出:
['Self-tightening belts', 'Rear seat belts', 'Active head restraints']
在这种情况下,词典列表可以解决熊猫提出的形状问题,如果其中一个词典的某些条目具有可变长度的列表项,则当您尝试将词典保存在熊猫数据框中时,
为了更好的理解,某些词典的名称进行了更改:
adBasicInfo = {} # 1.st dictionary
adOtherInfo = {} # 2.nd dictionary
adFullInfo = {} # Merged dictionary
adFullList = [] # List for appending merged dictionaries
# In each iteration merge dicts and append them in the list
for div in soup.findAll('a', {'class': 'result'}):
..some code...
adBasicInfo = {
u'adLink':adLink,
u'adThumbImg':...some code...,
u'adCounty':...some code...
}
adOtherInfo = getFullAdInfo(adLink) # Get complex dict
adFull = {**adBasicInfo,**adOtherInfo} # Merge dicts
adFullList.append(adFull) # Append dicts to list
# Save final version of list as pandas dataframe
adFullDF = pd.DataFrame(data=adFullList) # Save final list to dataframe