在函数之间传递两个变量

时间:2019-10-24 12:22:50

标签: python

编辑 我搞砸了!真抱歉!问题与最后2条印刷声明无关。当我用尽主意时添加了那些。整个问题在于将titlefinal_price的形式check_price传递给send_email并在身体和主体中使用它们。

我刚刚撞墙,不知道在这里找到答案。 我已尝试根据YouTube上的一些指南创建网络抓取工具。但是,由于我缺乏知识和经验,我一直困扰于如何将2个变量titlefinal_price从函数check_price()传递给函数send_mail()

的问题。

如果我尝试仅使用纯文本发送不带这些变量的电子邮件,一切都会正常工作。

import os
import smtplib
import requests
from email.message import EmailMessage
from bs4 import BeautifulSoup

EMAIL_ADDRESS = os.environ.get('GMAIL_USER')
EMAIL_PASSWORD = os.environ.get('GMAIL_PASSWORD')

URL_AMZ = 'https://www.amazon.de/Logitech-kabelgebundene-fortschrittlicher-Muskelbelastung-fortschrittliche/dp/B07FNHV4MW/ref=sr_1_3?__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91&crid=26227QRRLWQHF&keywords=logitech+mx+vertical&qid=1571861245&sprefix=logitech+mx+%2Caps%2C342&sr=8-3'
# URL_MBNK = 'https://www.mbank.pl/serwis-ekonomiczny/kursy-walut/'
URL_GGL ='https://www.google.com/search?rlz=1C1GCEU_plPL839PL839&sxsrf=ACYBGNSHqUQOq6lZRXHyeKLPAd0peUegqg%3A1571862894642&ei=brmwXevuJuaFk74P1Mi12A8&q=euro&oq=euro&gs_l=psy-ab.3..0i71l8.0.0..1236884...0.2..0.0.0.......0......gws-wiz.D2K7kmd_GB8&ved=0ahUKEwjr3eHLnbPlAhXmwsQBHVRkDfsQ4dUDCAs&uact=5'


headers = {"User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'}

def check_price():
    # global title
    # global final_price
    page_amaz = requests.get(URL_AMZ, headers=headers)
    # page_mbnk = requests.get(URL_MBNK, headers=headers)
    page_ggl = requests.get(URL_GGL, headers=headers)

    soup_amaz = BeautifulSoup(page_amaz.content, 'html.parser')
    # soup_mbnk = BeautifulSoup(page_mbnk.content, 'html.parser')
    soup_ggl = BeautifulSoup(page_ggl.content, 'html.parser')


    title = soup_amaz.find(id='productTitle').get_text()
    price = soup_amaz.find(id='priceblock_ourprice').get_text()
    converted_price = float(price[0:-2].replace(',','.'))

    # convert_ratio = soup_mbnk.find(id="currencies").get_text()
    convert_ratio_ggl = soup_ggl.find('div','dDoNo vk_bk').get_text()
    clean_convert_ratio = float(convert_ratio_ggl[0:4].replace(',','.'))

    final_price = converted_price * clean_convert_ratio 

    if(final_price > 200):
        send_email()

    return title, final_price

def send_email():
    title, final_price = check_price()
    msg = EmailMessage()
    msg['Subject'] = f'Zmiana ceny produktu {title}' #% (title)
    msg['From'] = EMAIL_ADDRESS
    msg['To'] = 'I know it's bit to late... but here was my email'
    msg.set_content(f'Cena {final_price} -- Link:{URL_AMZ}') # % (final_price  ,URL_AMZ))

    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
        smtp.login(EMAIL_ADDRESS , EMAIL_PASSWORD)
        smtp.send_message(msg)
        print("Mail Wysłany")
#print(title)
#print(final_price)

编辑 问题已解决。 我非常感谢您的协助。

在固定和清除的代码下方。

import requests
import smtplib
import os
from bs4 import BeautifulSoup
from email.message import EmailMessage

EMAIL_ADDRESS = os.environ.get('GMAIL_USER')
EMAIL_PASSWORD = os.environ.get('GMAIL_PASSWORD')

URL_AMZ = 'https://www.amazon.de/Logitech-kabelgebundene-fortschrittlicher-Muskelbelastung-fortschrittliche/dp/B07FNHV4MW/ref=sr_1_3?__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91&crid=26227QRRLWQHF&keywords=logitech+mx+vertical&qid=1571861245&sprefix=logitech+mx+%2Caps%2C342&sr=8-3'
URL_GGL ='https://www.google.com/search?rlz=1C1GCEU_plPL839PL839&sxsrf=ACYBGNSHqUQOq6lZRXHyeKLPAd0peUegqg%3A1571862894642&ei=brmwXevuJuaFk74P1Mi12A8&q=euro&oq=euro&gs_l=psy-ab.3..0i71l8.0.0..1236884...0.2..0.0.0.......0......gws-wiz.D2K7kmd_GB8&ved=0ahUKEwjr3eHLnbPlAhXmwsQBHVRkDfsQ4dUDCAs&uact=5'


headers = {"User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'}

def check_price():

    page_amaz = requests.get(URL_AMZ, headers=headers)
    page_ggl = requests.get(URL_GGL, headers=headers)

    soup_amaz = BeautifulSoup(page_amaz.content, 'html.parser')
    soup_ggl = BeautifulSoup(page_ggl.content, 'html.parser')

    title = soup_amaz.find(id='productTitle').get_text()
    final_title = title.strip() # variable title contain monstrocity that contained 5 8x \r\n above and belowe title.
    price = soup_amaz.find(id='priceblock_ourprice').get_text()
    converted_price = float(price[0:-2].replace(',', '.'))

    convert_ratio_ggl = soup_ggl.find('div','dDoNo vk_bk').get_text()
    clean_convert_ratio = float(convert_ratio_ggl[0:4].replace(',','.'))

    final_price = converted_price * clean_convert_ratio

    if final_price > 200:
        send_email(final_title, final_price)


def send_email(final_title, final_price):
    msg = EmailMessage()
    msg['Subject'] = f'Zmiana ceny produktu {final_title}'
    msg['From'] = EMAIL_ADDRESS
    msg['To'] = 'EMAIL_ADDRESS'

    msg.set_content(f'Cena {final_price} -- Link:{URL_AMZ}') 

    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
        smtp.login(EMAIL_ADDRESS , EMAIL_PASSWORD)
        smtp.send_message(msg)
        print("Mail Wysłany")
check_price()

后来我碰到了Send_email()产生错误的墙壁 ValueError: Header values may not contain linefeed or carriage return characters 这是由变量title引起的(不是从上面和下面的所有空行中剥离出来的。

再一次,谢谢大家。

5 个答案:

答案 0 :(得分:4)

我相信您获取变量titlefinal_price的方法很好,应该可以。

但是,最后两个打印不起作用,因为它们在send_email()函数之外,因此titlefinal_price是未知的。您是否尝试过将打印内容放入函数中并调用它?

更新:

我现在看到了错误,您在send_email()内调用check_price(),在check_price()内调用send_email(),这可能导致无止境循环

要解决此问题,如果您要调用的函数是check_price(),则可以使send_email()接受两个参数并在调用时传递它们。因此,您可以在check_price()中进行以下操作:

...
if(final_price > 200):
   send_email(title,final_price)
...

,然后send_email如下:

def send_email(title,final_price):
   msg = EmailMessage()
   ...

更新2:

您还使用单引号内的撇号:

'I know it's bit to late... but here was my email'

您应该这样做:

"I know it's bit to late... but here was my email"

答案 1 :(得分:0)

您的错误是由于您的打印语句不在功能范围内而引起的。两种解决方案。

选项1

title, final_price = check_price() 
print(title) 
print(final_price)

选项2

或者直接在您的邮件发送功能内

def send_email(): 
    title, final_price = check_price() 
    msg = EmailMessage() 
    msg['Subject'] = f'Zmiana ceny produktu {title}' #% (title) 
    msg['From'] = EMAIL_ADDRESS 
    msg['To'] = EMAIL_ADDRESS  
    msg.set_content(f'Cena {final_price} -- Link:{URL_AMZ}') # % (final_price ,URL_AMZ)) 
    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp: 
         smtp.login(EMAIL_ADDRESS , EMAIL_PASSWORD) 
         smtp.send_message(msg) print("Mail Wysłany")
    print(title) 
    print(final_price) 

错误

Traceback (most recent call last):
  File "/mnt/c/_KOD_/github/Web-Scrapper/Scrapper.py", line 58, in <module>
    print(title)
NameError: name 'title' is not defined

答案 2 :(得分:0)

要将变量传递到函数中,在定义函数时需要在方括号中定义它们。

def functionName(variable1, variable2)

然后要使用它们,请在使用它们时将值传递给函数。

send_email(title, price)

使用以下命令从上一个函数中获得这些值之后:

title, price = check_price()

答案 3 :(得分:0)

打印错误的问题是由于全局名称空间中不存在这些变量,仅是定义它们的函数的本地名称空间中存在。

以下内容可以解决您的问题(已整理):

import os
import smtplib
import requests
from email.message import EmailMessage
from bs4 import BeautifulSoup

EMAIL_ADDRESS = os.environ.get('GMAIL_USER')
EMAIL_PASSWORD = os.environ.get('GMAIL_PASSWORD')

URL_AMZ = 'long-url-string'
URL_GGL = 'long-url-string'

headers = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'}


def check_price():

    page_amaz = requests.get(URL_AMZ, headers=headers)
    page_ggl = requests.get(URL_GGL, headers=headers)

    soup_amaz = BeautifulSoup(page_amaz.content, 'html.parser')
    soup_ggl = BeautifulSoup(page_ggl.content, 'html.parser')

    title = soup_amaz.find(id='productTitle').get_text()
    price = soup_amaz.find(id='priceblock_ourprice').get_text()
    converted_price = float(price[0:-2].replace(',', '.'))

    convert_ratio_ggl = soup_ggl.find('div','dDoNo vk_bk').get_text()
    clean_convert_ratio = float(convert_ratio_ggl[0:4].replace(',','.'))

    final_price = converted_price * clean_convert_ratio

    if final_price > 200:
        send_email(title, final_price)

    print(title)
    print(price)


def send_email(title, final_price):

    msg = EmailMessage()
    msg['Subject'] = f'Zmiana ceny produktu {title}'
    msg['From'] = EMAIL_ADDRESS
    msg['To'] = 'EMAIL_ADDRESS'
    msg.set_content(f'Cena {final_price} -- Link:{URL_AMZ}') # % (final_price  ,URL_AMZ))

    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
        smtp.login(EMAIL_ADDRESS , EMAIL_PASSWORD)
        smtp.send_message(msg)
        print("Mail Wysłany")

答案 4 :(得分:0)

您要执行的操作是使send_email()接受要传递的两个变量。所以send_email(title, final_price)

然后在您的check_price()函数的末尾,无需返回值,只需执行send_email(title, final_price)

基于@ raquel.horta的回复,您正在两个函数中调用这两个函数。我认为您不是要在check_price()中再次调用send_email(),而是用它来获取值。但事实是,它将重新运行整个功能以获得这些值。因此,从title, final_price = check_price()中删除send_email(),只需在if语句之后调用send_email

if (final_price > 200):
    send_email(title, final_price)

OR

如果您想保持代码不变,则需要了解在执行return title, final_price时会创建带有两个值的列表。

您可以这样做:

title = check_price()[0]
final_price = check_price()[1]

我举了一个简单的例子供您理解:

def mee():
    a = "This"
    b = "That"
    return a,b

def printt(a, b):
    print("Printing from here")
    print(a)
    print(b)

printt(mee()[0], mee()[1])

输出:

daudnadeem: daudn$ python3.7 test.py
Printing from here
This
That

我希望这会有所帮助!

相关问题