Python Веб-парсинг: проблема с отображением дублирования и вывода - PullRequest
0 голосов
/ 07 мая 2020

Где-то есть проблема с моим кодом, которую я пробовал, но не могу определить. Это связано с тем, что вывод циклов не отображается и правильно вставляется в мою БД. Я хотел бы, чтобы каждая очищенная строка данных была напечатана как вывод, а затем вставлена ​​в таблицу базы данных. Пока что все, что я получаю, это всего лишь один результат, напечатанный как дубликат много раз (даже не имеет правильной цены).

Фактический текущий выход:

Ford C-MAX 2019 1.1 Petrol 0
Ford C-MAX 2019 1.1 Petrol 0
Ford C-MAX 2019 1.1 Petrol 0
...

Желаемый результат согласно объявления на веб-страницах (просто пример, так как это динамика c):

Ford C-MAX 2019 1.1 Petrol 15950
Ford C-MAX 2014 1.6 Diesel 12000
Ford C-MAX 2011 1.6 Diesel 9000
...

Код:

from __future__ import print_function
import requests
import re
import locale
import time
from time import sleep
from random import randint
from currency_converter import CurrencyConverter
c = CurrencyConverter()
from bs4 import BeautifulSoup
import pandas as pd
from datetime import date, datetime, timedelta
import mysql.connector
import numpy as np
import itertools

locale.setlocale( locale.LC_ALL, 'en_US.UTF-8' )

pages = np.arange(0, 210, 30)

entered = datetime.now()
make = "Ford"
model = "C-MAX"


def insertvariablesintotable(make, model, year, liter, fuel, price, entered):
    try:
        cnx = mysql.connector.connect(user='root', password='', database='FYP', host='127.0.0.2', port='8000')
        cursor = cnx.cursor()

        cursor.execute('CREATE TABLE IF NOT EXISTS ford_cmax ( make VARCHAR(15), model VARCHAR(20), '
                       'year INT(4), liter VARCHAR(3), fuel VARCHAR(6), price INT(6), entered TIMESTAMP) ')

        insert_query = """INSERT INTO ford_cmax (make, model, year, liter, fuel, price, entered) VALUES (%s,%s,%s,%s,%s,%s,%s)"""
        record = (make, model, year, liter, fuel, price, entered)

        cursor.execute(insert_query, record)

        cnx.commit()

    finally:
        if (cnx.is_connected()):
            cursor.close()
            cnx.close()

for response in pages:

    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
    response = requests.get("https://www.donedeal.ie/cars/Ford/C-MAX?start=" + str(response), headers=headers)
    soup = BeautifulSoup(response.text, 'html.parser')

    cnx = mysql.connector.connect(user='root', password='', database='FYP', host='127.0.0.2', port='8000')
    cursor = cnx.cursor()

    for details in soup.findAll('ul', attrs={'class': 'card__body-keyinfo'}):

        details = details.text
        #print(details)
        year = details[:4]
        liter = details[4:7]
        fuel = details[8:14] #exludes electric which has 2 extra
        mileage = re.findall("[0-9]*,[0-9][0-9][0-9]..." , details)
        mileage = ''.join(mileage)
        mileage = mileage.replace(",", "")
        if "mi" in mileage:
            mileage = mileage.rstrip('mi')
            mileage = round(float(mileage) * 1.609)
        mileage = str(mileage)
        if "km" in mileage:
            mileage = mileage.rstrip('km')
        mileage = mileage.replace("123" or "1234" or "12345" or "123456", "0")

    for price in soup.findAll('p', attrs={'class': 'card__price'}):

        price = price.text
        price = price.replace("No Price", "0")
        price = price.replace("123" or "1234" or "12345" or "123456", "0")
        price = price.replace(",","")
        price = price.replace("€", "")
        if "p/m" in price:
            #price = price[:-3]
            price = price.rstrip('p/m')
            price = "0"
        if "£" in price:
            price = price.replace("£", "")
            price = c.convert(price, 'GBP', 'EUR')
            price = round(price)

    print(make, model, year, liter, fuel, price)

    #insertvariablesintotable(make, model, year, liter, fuel, price, entered) #same result as above

1 Ответ

1 голос
/ 07 мая 2020

Я взглянул на ваш код и на веб-сайт, с которого вы пытаетесь получить данные, и похоже, что вы извлекаете страницу, а затем перебираете все цены, которые вы получаете с этой страницы, используя price как переменную, но перезаписывая ее каждый раз, когда вы вводите для l oop. То же самое и с вашими данными for l oop.

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

make = "Ford"
model = "C-MAX"
price_list = [] # we will store prices here
details_list = [] # and details like year, liter, mileage there
for response in range(1,60,30): # I changed to a range loop for testing

    headers = {
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
    }
    response = requests.get(
        "https://www.donedeal.ie/cars/Ford/C-MAX?start=" + str(response),
        headers=headers,
    )
    soup = BeautifulSoup(response.text, "html.parser")
    count = 0
    for details in soup.findAll("ul", attrs={"class": "card__body-keyinfo"}):
        if count == 30:
            break # Takes us out of the for loop
        details = details.text
        # print(details)
        year = details[:4]
        liter = details[4:7]
        fuel = details[8:14]  # exludes electric which has 2 extra
        mileage = re.findall("[0-9]*,[0-9][0-9][0-9]...", details)
        mileage = "".join(mileage)
        mileage = mileage.replace(",", "")
        if "mi" in mileage:
            mileage = mileage.rstrip("mi")
            mileage = round(float(mileage) * 1.609)
        mileage = str(mileage)
        if "km" in mileage:
            mileage = mileage.rstrip("km")
        mileage = mileage.replace("123" or "1234" or "12345" or "123456", "0")
        details_list.append((year, liter, fuel, mileage)) # end of one loop go-through, we append
        count += 1 We update count value 
    count = 0
    for price in soup.findAll("p", attrs={"class": "card__price"}):
        if count == 30:
            break # Takes us out of the for loop
        price = price.text
        price = price.replace("No Price", "0")
        price = price.replace("123" or "1234" or "12345" or "123456", "0")
        price = price.replace(",", "")
        price = price.replace("€", "")
        if "£" in price:
            price = price.replace("£", "")
            price = c.convert(price, "GBP", "EUR")
            price = round(price)
        if "p/m" in price:
            # price = price[:-3]
            price = price.rstrip("p/m")
            price = "0"
        else:
            price_list.append(price) # end of loop go-through, we append but only if it is not a "p/m" price
            count += 1 # We update count value only when a value is appended to the list

for i in range(len(price_list)):
    print(
    make,
    model,
    details_list[i][0],
    details_list[i][1],
    details_list[i][2],
    price_list[i],
)
    #add your insertvariablesintotable(make,model,details_list[i][0], details_list[i][1],details_list[i][2],price_list[i]) there

Изменить: я не добавлял цены за п / м в список поскольку они делали разной длины details_list и price_list. Если вы хотите добавить и цены p / m, вам придется переделать код. Кроме того, вы не хотите, чтобы 3 автомобиля были в самом низу страницы, поскольку это может быть не Ford C -MAX, а другие модели, возможно, даже других производителей.

...