【问题标题】:How would one go about appending all values attached to a variable to one list? [closed]如何将附加到变量的所有值附加到一个列表中? [关闭]
【发布时间】:2022-08-19 16:11:16
【问题描述】:

我有一些代码使用 bs4 从主要转售网站获取价格和其他数据,然后将其附加到 JSON 格式。我想将所有价格附加到一个列表中,这样我就可以对它们进行平均并找到平均零售价。

不幸的是,我尝试过的所有东西似乎只为每个价格创建了一个不同的列表:

try:
  price = item.select_one(\'.s-item__price\').text
except:
  price = None

        
        
value = Decimal(sub(r\'[^\\d.]\', \'\', price))
a = str(value)
b = list(a.split())

输出 b 结果:

[\'20.00\']
[\'199.95\']
[\'48.99\']
[\'100.00\']
[\'119.00\']
[\'19.99\']
[\'35.00\']
[\'85.00\']
[\'39.00\']
[\'27.66\']
[\'75.00\']

如图所示,它返回多个无法求和的列表。输出价格会返回类似的结果,不带括号。我使用 Decimal 去除本地化符号的价格,得到小数。然后我将其转换为字符串,因为它给了我一个错误,说浮点数不可迭代。使用 itertools 也不起作用。

如何获得如下格式?

prices = [20.00, 199.45, ... 75.00]

抱歉,如果这是一个明显的问题,我是 Python 的新手。

  • 请出示minimal reproducible example,不要试图将python代码硬塞进JavaScript sn-p
  • 当你说“输出这个结果:\”时,输出什么?我假设它的b
  • @tygzy 是的,我已经相应地进行了编辑
  • @MadPhysicist LOL 那个比喻
  • @j1-lee 它显示的字符串类似于 \"b\" 的输出,但没有括号。如果有些东西不清楚,我再次道歉,因为如前所述,我对此很陌生。

标签: python list web-scraping beautifulsoup python-jsons


【解决方案1】:

假设您使用产品迭代 ResultSet,只需查找价格并将其附加到 list

data = []
for item in soup.select('.s-item__wrapper'):
        data.append(
            re.sub(r'[^\d.]', '', item.find('span', {'class': 's-item__price'}).text) if item.find('span', {'class': 's-item__price'}) else None
        )

例子

import requests, re
from bs4 import BeautifulSoup

page = requests.get('https://www.ebay.co.uk/sch/i.html?_from=R40&_trksid=p2334524.m570.l1311&_nkw=python+programming&_sacat=0&LH_TitleDesc=0&_odkw=python&_osacat=0')
soup=BeautifulSoup(page.text)

data = []
for item in soup.select('.s-item__wrapper'):
        data.append(
            re.sub(r'[^\d.]', '', item.find('span', {'class': 's-item__price'}).text) if item.find('span', {'class': 's-item__price'}) else None
        )
print(data)
输出
['20.00', '3.31', '5.22', '3.19', '4.52', '9.99', '5.71', '7.69', '3.54', '9.99', '3.30', '8.95', '5.63', '19.99', '33.53', '62.04', '32.16', '43.42', '5.00', '8.00', '3.74', '10.00', '7.40', '42.40', '25.03', '9.03', '11.22', '29.51', '11.86', '30.45', '33.80', '22.99', '44.94', '29.74', '7.68', '60.98', '23.81', '9.83', '15.28', '70.61', '28.67', '100.00', '16.75', '14.92', '13.33', '13.54', '36.66', '20.16', '6.42', '16.85', '20.00', '4.82', '18.99', '31.34', '19.30', '100.00', '29.66', '54.52', '10.64', '3.82', '100.00', '15.20', '27.18', '14.17', '20.00', '29.99', '27.00', '38.51', '18.98', '100.00', '106.97', '36.81']

另外,如果您想抓取多个信息 - 建议避免使用一堆列表,最好使用包含结构化数据作为 dicts 的单个列表:

data = []
for item in soup.select('.s-item__wrapper')[1:]:
        data.append({
            'name':item.h3.text,
            'price':re.sub(r'[^\d.]', '', item.find('span', {'class': 's-item__price'}).text) if item.find('span', {'class': 's-item__price'}) else None
        })

【讨论】:

  • 这种方法非常有效。万分感谢! :)
【解决方案2】:

这应该可行,我使用了列表理解,这相当于使用 for 循环,如下所示:

try:
  price = item.select_one('.s-item__price').text
except:
  price = None   
        
value = Decimal(sub(r'[^\d.]', '', price))
a = str(value)
b = list(a.split())
prices = list()

for x in b:
    prices.append(float(x[0]))

或者像我一样:

try:
  price = item.select_one('.s-item__price').text
except:
  price = None   
        
value = Decimal(sub(r'[^\d.]', '', price))
a = str(value)
b = list(a.split())
prices = [float(y) for x in b for y in x]

【讨论】:

  • 我也尝试了类似的方法,现在使用 int 运行它会返回无效的文字。另一方面,删除 int 会删除几个单独列表的相同结果。
  • 我的错,你应该使用 float() 而不是 int() 因为整数只是整数
  • 有效,但再次每个项目都在不同的列表中,而不是一个可以轻松平均的列表。
  • 我不知道你在说什么,如果它是一个 2D 列表,因为从你给它的内容来看,这应该把它放在一个列表中。
  • 我也是这么想的。 Beautifulsoup 固有的输出方式可能存在问题,因此我将对此进行研究。尽管如此,还是感谢您的帮助。
猜你喜欢
  • 2016-08-01
  • 2023-03-23
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多