Html 美孚集团4&;Python-将多个页面放入数据框架

Html 美孚集团4&;Python-将多个页面放入数据框架,html,pandas,dataframe,parsing,beautifulsoup,Html,Pandas,Dataframe,Parsing,Beautifulsoup,我有一些代码,可以通过多个页面收集在线零售商的描述、价格和旧价格(如果有售)。我希望将其导出到数据帧中,但遇到了以下错误: ValueError:传递的值的形状是(13210),索引意味着(33210)。 from bs4 import BeautifulSoup import requests import time import pandas as pd # Start Timer then = time.time() # Headers headers = {"User-Agent":

我有一些代码,可以通过多个页面收集在线零售商的描述、价格和旧价格(如果有售)。我希望将其导出到数据帧中,但遇到了以下错误:

ValueError:传递的值的形状是(13210),索引意味着(33210)。

from bs4 import BeautifulSoup
import requests
import time
import pandas as pd

# Start Timer
then = time.time()

# Headers
headers = {"User-Agent": "Mozilla/5.0"}

# Set HTTPCode = 200 and Counter = 1
Code = 200
i = 1

scraped_data = []
while Code == 200:

    # Put url together
    url = "https://www.asos.com/women/jumpers-cardigans/cat/?cid=2637&page="
    url = url + str(i)

    # Request URL
    r = requests.get(url, allow_redirects=False, headers=headers)  # No redirects to allow infinite page count
    data = r.text
    Code = r.status_code

    # Soup
    soup = BeautifulSoup(data, 'lxml')

    # For loop each product then scroll through title price, old price and description
    divs = soup.find_all('article', attrs={'class': '_2qG85dG'}) # want to cycle through each of these

    for div in divs:

        # Get Description
        Description = div.find('div', attrs={'class': '_3J74XsK'})
        Description = Description.text.strip()
        scraped_data.append(Description)

        # Fetch TitlePrice
        NewPrice = div.find('span', attrs={'data-auto-id':'productTilePrice'})
        NewPrice = NewPrice.text.strip("£")
        scraped_data.append(NewPrice)

        # Fetch OldPrice
        try:
            OldPrice = div.find('span', attrs={'data-auto-id': 'productTileSaleAmount'})
            OldPrice = OldPrice.text.strip("£")
            scraped_data.append(OldPrice)
        except AttributeError:
            OldPrice = ""
            scraped_data.append(OldPrice)

    print('page', i, 'scraped')
        # Print Array
        #array = {"Description": str(Description), "CurrentPrice": str(NewPrice), "Old Price": str(OldPrice)}
        #print(array)
    i = i + 1
else:
    i = i - 2
    now = time.time()
    pd.DataFrame(scraped_data, columns=["A", "B", "C"])
    print('Parse complete with', i, 'pages' + ' in', now-then, 'seconds')

现在,您的数据根据一种算法添加到列表中,我可以这样描述:

  • 加载网页
  • 附加到列表值A
  • 附加到列表值B
  • 附加到列表值C
  • 这将为数据集的每次运行创建以下内容:

    [A1, B1, C1, A2, B2, C2]
    
    只有一列包含数据,这就是熊猫告诉您的。要正确构造数据帧,您需要将其交换为一种格式,在该格式中,每行条目上都有一个三值元组(heh),如:

    或者,以我更喜欢的方式,因为它对编码错误和数据长度不一致更具鲁棒性:将每一行创建为列字典。因此,

    rowdict_list = []
    for row in data_source:
        a = extract_a()
        b = extract_b()
        c = extract_c()
        rowdict_list.append({'column_a': a, 'column_b': b, 'column_c': c})
    

    数据帧的构造非常简单,无需使用
    df=pd显式指定构造函数中的列。数据帧(rowdict_list)
    您可以使用数组字典创建数据帧

    您可能希望将数组dict的值设置为空列表,这样您就可以将网页中的值附加到正确的列表中。同时将数组变量移到while循环之外

    array = {"Description": [], "CurrentPrice": [], "Old Price": []}
    scraped_data = []
    while Code == 200:
        ...
    
    在前面定义数组变量的那一行,您可能希望像这样附加描述、价格和旧价格值

    array['Description'].append(str(Description))
    array['CurrentPrice'].append(str(NewPrice))
    array['Old Price'].append(str(OldPrice))
    
    然后可以使用数组变量创建数据帧

    pd.DataFrame(array)
    
    所以最终的解决方案看起来像

    array = {"Description": [], "CurrentPrice": [], "Old Price": []}
    scraped_data = []
    while Code == 200:
       ...
    
    最后,确保已在模块顶部导入熊猫
    import pandas as pd

    它几乎肯定是由构造函数提出的,因为您传递的数据的形状与您所说的不一样be@ifly6是的,它应该是3列,描述,价格,旧价格。找到的每个项都有n行,但我不知道我要去哪里,但刮取的数据没有这种形式。您的代码将在每个循环上附加三个值。考虑将每一行更改为基于字典的表示,您从dictionaries@ifly6谢谢你的建议。我是Python新手,所以不要完全理解这个概念。谢谢施瓦布!这是一个小的调整工作。我不得不将array={“Description”:[],“CurrentPrice”:[],“Old Price”:[]}移动到while循环之外,但除此之外,它非常棒。@Rosstopher我已经用while循环的编辑更新了答案,以防将来有人遇到这个问题非常聪明,熊猫之王
    array = {"Description": [], "CurrentPrice": [], "Old Price": []}
    scraped_data = []
    while Code == 200:
       ...
    
        # For loop
        for div in divs:
    
            # Get Description
            Description = div.find('h3', attrs={'class': 'product__title'})
            Description = Description.text.strip()
    
            # Fetch TitlePrice
            try:
                NewPrice = div.find('div', attrs={'class': 'price product__price--current'})
                NewPrice = NewPrice.text.strip()
            except AttributeError:
                NewPrice = div.find('p', attrs={'class': 'price price--reduced'})
                NewPrice = NewPrice.text.strip()
    
            # Fetch OldPrice
            try:
                OldPrice = div.find('p', attrs={'class': 'price price--previous'})
                OldPrice = OldPrice.text.strip()
            except AttributeError:
                OldPrice = ""
    
            array['Description'].append(str(Description))
            array['CurrentPrice'].append(str(NewPrice))
            array['Old Price'].append(str(OldPrice))
            # Print Array
            print(array)
        df = pd.DataFrame(array)
        i = i + 1
    else:
        i = i - 2
        now = time.time()
        print('Parse complete with', i, 'pages' + ' in', now - then, 'seconds')