【问题标题】:Remove unwanted characters from string with BeautifulSoup Python when selecting words from string从字符串中选择单词时,使用 BeautifulSoup Python 从字符串中删除不需要的字符
【发布时间】:2019-06-23 12:55:15
【问题描述】:

我是 Python 新手,仍然不了解它的所有内容及其功能,但我正在接近我想要实现的目标。

基本上我有程序从网站上抓取我想要的数据,但是当它从“specs”字符串中打印选定的单词/项目时,它也会从字符串中打印 [ ] 和 '' 等字符。

示例是我试图从 li 列表中获取“齿轮箱”类型、“燃料”类型和“里程”,我已将其转换为带有工厂的字符串,然后从中选择特定项目细绳。

我现在的程序是这样的:

['手动']['汽油']['86,863英里']

我想要实现的是这样的打印结果:

手动,汽油,86,863 英里

当导出到我的 .csv 中的单独列时,应显示在相应标题下的正确列中。

我已尝试 .text 仅删除文本,但它显示为 'list' object has no attribute 'text' 错误。


import csv 

import requests
from bs4 import BeautifulSoup

outfile = open('pistonheads.csv','w', newline='')
writer = csv.writer(outfile)
writer.writerow(["Link", "Make", "Model", "Price", "Image Link", 
"Gearbox", "Fuel", "Mileage"])

url = 'https://www.pistonheads.com/classifieds?Category=used- cars&Page=1&ResultsPerPage=100'

get_url = requests.get(url)
get_text = get_url.text

soup = BeautifulSoup(get_text, 'html.parser')
car_link = soup.find_all('div', 'listing-headline', 'price')

for div in car_link:
    links = div.findAll('a')
    for a in links:
        link = ("https://www.pistonheads.com" + a['href'])
        make = (a['href'].split('/')[-4])
        model = (a['href'].split('/')[-3])
        price = a.find('span').text.rstrip()
        image_link = a.parent.parent.find('img')['src']
        image = ("https:") + image_link
        vehicle_details = a.parent.parent.find('ul', class_='specs')
        specs = list(vehicle_details.stripped_strings)
        gearbox = specs[3:]
        fuel = specs[1:2]
        mileage = specs[0:1]
        writer.writerow([link, make, model, price, image, gearbox, fuel, mileage])
        print(link, make, model, price, image, gearbox, fuel, mileage)

outfile.close()

【问题讨论】:

  • 当你操作的时候,specs变成了一个list对象,然后你使用了list specs的切片,显然结果仍然是list..

标签: python beautifulsoup screen-scraping


【解决方案1】:

欢迎来到 StackOverflow!

因此,您的脚本还有很多需要改进的地方。你快到了!

  • specs = list(vehicle_details.stripped_strings) 是解析为列表的生成器。实际上,您可以通过索引访问您想要的东西。例如,mileage 可以简单地为 specs[0]
  • 你得到额外的[]的问题是由于你使用了切片mileage = specs[0:1]造成的。从文档中,索引返回一个项目,切片返回一个新列表。见lists introduction
  • (可选) 最后,要在一行中获取所有这些信息,您可以从规格列表中​​进行多项分配。见multiple assignments.
mileage, fuel, _, gearbox = specs
  • 额外提示如有疑问,请使用pdb
mileage = specs[0]
import pdb; pdb.set_trace()  # temp set on one line so you can remove it easily after
# now you can interactively inspect your code
(Pdb) specs

祝你好运!享受 Python!

【讨论】:

    【解决方案2】:

    如果你想从列表中获取字符串,也许你可以这样做

    gearbox = specs[3:][0] if specs[3:] else '-'
    fuel = specs[1:2][0]  if specs[1:2] else '-'
    mileage = specs[0:1][0]  if specs[0:1] else '-' 
    

    但是这种方式或 aldnav 的答案会给出错误的结果,甚至会抛出错误

    ValueError: 没有足够的值来解压

    通常我会先提取父容器,而不是选择子容器(a)然后转到父容器。

    # helper to get dynamic specs element
    def getSpec(element, selector):
        spec = element.select_one(selector)
        return spec.nextSibling.string.strip() if spec else '-'
    
    soup = BeautifulSoup(get_text, 'html.parser')
    results = soup.find_all('div', class_="result-contain")
    
    for car in results:
        a = car.find('a')
        if not a:
            continue
        link = ("https://www.pistonheads.com" + a['href'])
        make = (a['href'].split('/')[-4])
        model = (a['href'].split('/')[-3])
        price = a.find('span').text.rstrip()
        image_link = car.find('img')['src']
        image = ("https:") + image_link
    
        if not car.find('ul', class_='specs'):
            gearbox = fuel = mileage = '-'
        else:
            gearbox = getSpec(car, '.location-pin-4')
            fuel = getSpec(car, '.gas-1')
            mileage = getSpec(car, '.gauge-1')
        print(gearbox, fuel, mileage)
        writer.writerow([link, make, model, price, image, gearbox, fuel, mileage])
        #print(link, make, model, price, image, gearbox, fuel, mileage)
    
    outfile.close()
    

    【讨论】:

    • 感谢@cieunteung,实际上效果很好!我刚刚使用了 (if specs[3:] else '-') 版本,它运行良好。那谢谢啦!我遇到的唯一问题是我的“价格”行,它在每个价格输出之前打印所有带有奇怪字符 (¬) 的价格。 IE。这就是它的印刷品 ¬£18,995。知道如何在每次价格输出之前删除这个字符吗?
    • 我在我的环境中看不到该字符,您可以替换它或以utf-8 格式写入文件或使用.strip() 而不是.rstrip() 的价格
    • 奇怪的是,我可以看到它在崇高的文本中看起来不错,但是当我将它写入 .csv 时,它会显示该字符。
    • 另外我现在正在寻找让程序解析同一网址的多个页面,即第 2 页、第 3 页等,您能帮我解决这个问题吗?这是链接参数:“pistonheads.com/classifieds?Category=used-cars&Page=
    • 你试过用utf-8写csv吗?对于另一个问题,请创建另一个帖子。
    猜你喜欢
    • 2011-02-16
    • 2011-12-24
    • 1970-01-01
    • 2013-04-17
    • 2015-08-06
    • 2017-03-27
    • 2011-08-13
    相关资源
    最近更新 更多