bs4 Python извлекает значение из <span></span> в .csv, печатая один и тот же результат снова и снова - PullRequest
0 голосов
/ 28 января 2019

Мне удалось создать очень примитивную программу для очистки данных автомобиля от поршневых головок и печати в файл .csv со ссылкой, маркой, моделью, и я работаю над получением цены, по которой я сталкиваюсь с проблемой.

Я хочу прокрутить цены до четвертого столбца в моем файле .csv (Price) и правильно распечатать цены для каждого транспортного средства на веб-сайте.

Я получаю печать только с одного автомобиля и повторяю ее снова и снова рядом с каждым автомобилем в файле .csv.

Я попытался soup.findAll и soup.find_all, чтобы увидеть, будет ли работать разбор нескольких элементов, но это только создает больший беспорядок.

Может ли кто-нибудь помочь?

Я также пытаюсь почистить изображение src и хотел бы напечатать его в другом столбце (5), который называется images.

import csv ; import requests

from bs4 import BeautifulSoup

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

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 = soup.find('span')
      writer.writerow([link, make, model, price])
      print(link, make, model, price)
outfile.close()

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Вы можете попробовать это:

import csv, requests, re
from urllib.parse import urlparse
from bs4 import BeautifulSoup as soup
d = soup(requests.get('https://www.pistonheads.com/classifieds?Category=used-cars&ResultsPerPage=100').text, 'html.parser')
def extract_details(_s:soup) -> list:
  _link = _s.find('a', {'href':re.compile('/classifieds/used\-cars/')})['href']
  _, _, make, model, *_ = _link[1:].split('/')
  price, img = _s.find('div', {'class':'price'}).text, [i['src'] for i in _s.find_all('img')]
  return [_link, make, model, price, 'N/A' if not img else img[0]]

with open('filename.csv', 'w') as f:
  _listings = [extract_details(i) for i in d.find_all('div', {'class':'ad-listing'}) if i.find('div', {'class':'price'})]
  write = csv.writer(f)
  write.writerows([['make', 'model', 'price', 'img'], *_listings])
0 голосов
/ 28 января 2019

Причина в том, что price = soup.find('span')

.find() захватит первый найденный элемент.И у вас есть это, глядя на ваш soup объект.Но где вы хотите, чтобы это выглядело, находится внутри вашего a, потому что это то, что вы просматриваете с помощью for a in links:

Я также добавляю .text, поскольку я предполагаю, что вы просто хотите текст, а невесь элемент тега.Т.е. price = a.find('span').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", 'Images'])

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
      image_link = a.parent.parent.find('img')['src']
      image = link + image_link
      writer.writerow([link, make, model, price, image])
      print(link, make, model, price, image)



outfile.close()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...