编辑
我搞砸了!真抱歉!问题与最后2条印刷声明无关。当我用尽主意时添加了那些。整个问题在于将title
和final_price
的形式check_price
传递给send_email
并在身体和主体中使用它们。
我刚刚撞墙,不知道在这里找到答案。
我已尝试根据YouTube上的一些指南创建网络抓取工具。但是,由于我缺乏知识和经验,我一直困扰于如何将2个变量title
和final_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
引起的(不是从上面和下面的所有空行中剥离出来的。
再一次,谢谢大家。
答案 0 :(得分:4)
我相信您获取变量title
和final_price
的方法很好,应该可以。
但是,最后两个打印不起作用,因为它们在send_email()函数之外,因此title
和final_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()
...
您还使用单引号内的撇号:
'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)
您的错误是由于您的打印语句不在功能范围内而引起的。两种解决方案。
title, final_price = check_price()
print(title)
print(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'] = 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
我希望这会有所帮助!