简体   繁体   中英

Removing elements from lists

i'm having trouble removing elements from lists . When an e-mail is send I want to remove from urls[] and prices[] the relative elements.

Ex. if email has: like a url an Iphone X and like a price 500€ and it had been sent, i want to "rewrite" the elements in urls[] and prices[] lists removing iphone's url and 500€

import requests
from bs4 import BeautifulSoup
import smtplib
import time

#   https://www.amazon.it/Corsair-Vengeance-Memorie-Desktop-Prestazioni/dp/B0143UM4TC
#   https://www.amazon.it/AMD-Ryzen-5-3600-Processori/dp/B07STGGQ18
#   https://www.amazon.it/Apple-iPhone-Grigio-Siderale-Ricondizionato/dp/B07985C44N

urls = []
prices=[]
all_product = []
n = int(input("Inserisci il numero di prodotti: "))

#agginge il link da controllare
print("\nInserisci i link:")
for i in range(0, n): 
    link = str(input()) 
    urls.append(link)    

#aggiunge il realtivi prezzi ai link
print("\nInserisci i prezzi:")
for i in range(0, n): 
    money = int(input()) 
    prices.append(money) 

#headers per i diversi motori di ricerca
headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0 Chrome/83.0.4103.97 Safari/537.36'}

def check_price():
    for url, price in zip(urls, prices):
        soup  = BeautifulSoup(requests.get(url, headers=headers).content, 'lxml')
        title = soup.find(id='productTitle').get_text(strip=True)    
        try:
            products = soup.find(id='priceblock_ourprice').get_text()
            fix_string = products.replace(",", ".")      
            converted_price = float(fix_string[0:5])
            all_product.append(converted_price)
            money_saved=converted_price-price
            if (converted_price<=price): 
                 #send email
                remove_link=str(url)
                remove_price=price
                if(urls.index(remove_link)&prices.index(remove_price)):
                    urls.pop((urls.index(remove_link)))
                    prices.pop(prices.index(remove_price))
         except AttributeError:
            print ("Prezzo non trovato, controlla se il prodotto ha un prezzo esposto")
    print(all_product)

In Python it is not good idea to remove from list which is used in for... in.... because when you remove element then other elements are moved (so next element is in place of removed element) but for doesn't know it and it jumps to next element on list and it skip element which was moved to place of removed element.

Better before loop create empty list ( keep_urls = [] ), inside loop append to this list elements which you want to keep ( keep_urls.append(url) ), and after loop assing this list to old variable ( urls = keep_urls ). After that you can run it all again and it will use list without removed element.

This code shows how I see it.

BTW: because adding data using input() is long and borring so I added code which read data from files.

import requests
from bs4 import BeautifulSoup
import smtplib
import time

# --- functions ---

def ask_for_data():
    urls = []
    prices = []

    n = int(input("Inserisci il numero di prodotti: "))

    #agginge il link da controllare
    print("\nInserisci i link:")

    for i in range(n): 
        link = input()
        urls.append(link)    

    #aggiunge il realtivi prezzi ai link
    print("\nInserisci i prezzi:")

    for i in range(n): 
        money = input()
        prices.append(money) 

    return urls, prices

def read_data():
    with open('urls.txt') as fh:
        text = fh.read()
        urls = text.split('\n')

    with open('prices.txt') as fh:
        text = fh.read()
        prices = text.split('\n')

    return urls, prices

def write_data(urls, prices):
    with open('urls.txt', 'w') as fh:
        text = "\n".join(urls)
        fh.write(text)

    with open('prices.txt', 'w') as fh:
        text = "\n".join(prices)
        fh.write(text)

def send_email(url, price, converted_price):
    #money_saved = converted_price-price
    print('TODO: send mail with', url, price, converted_price)

# --- main ---

# - start -
#urls, prices = ask_for_data()
urls, prices = read_data()

#headers per i diversi motori di ricerca
headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0 Chrome/83.0.4103.97 Safari/537.36'
}

while True:

    # - before loop -
    keep_urls = []
    keep_prices = []
    all_products = []

    # - loop -
    for url, price in zip(urls, prices):
        r = requests.get(url, headers=headers)
        #print(r.status_code)
        soup  = BeautifulSoup(r.content, 'lxml')
        title = soup.find(id='productTitle').get_text(strip=True)    
        try:
            products = soup.find(id='priceblock_ourprice').get_text()
            fix_string = products.replace(",", ".")      
            converted_price = float(fix_string[0:5])

            all_products.append(converted_price)

            if converted_price <= price: 
                send_email(url, price, converted_price)
            else:
                keep_urls.append(url)
                keep_prices.append(price)

         except AttributeError as ex:
            print('Ex:', ex)
            print("Prezzo non trovato, controlla se il prodotto ha un prezzo esposto")

    # - loop -
    urls = keep_urls
    prices = keep_prices

    print(all_products)

    time_sleep(60)

# - end -
write_data(urls, prices)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM