python - 编码监视器python
问题描述
我正在尝试为网站实施监视器。每当售罄的商品有货时,我都会收到一封电子邮件。(或者如果添加了新项目)
当我运行此代码时,输出是:进程以退出代码 0 完成。
我是 Python 的初学者,有什么问题吗?如何像 24/24 一样运行此代码?我会收到电子邮件吗?(显然我的地址、密码等中有我的信息)。
好像什么都没发生...
#import urllib2
import smtplib
try:
import urllib.request as urllib2
except ImportError:
import urllib2
import hashlib
import random
import time
# url to be scraped
url = "https://www.off---white.com/en/IT/men/products/blue-af1-mca#"
# time between checks in seconds
sleeptime = 60
def getHash():
# random integer to select user agent
randomint = random.randint(0, 7)
# User_Agents
# This helps skirt a bit around servers that detect repeaded requests from the same machine.
# This will not prevent your IP from getting banned but will help a bit by pretending to be different browsers
# and operating systems.
user_agents = [
'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
'Opera/9.25 (Windows NT 5.1; U; en)',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.142 Safari/535.19',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:8.0.1) Gecko/20100101 Firefox/8.0.1',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.151 Safari/535.19'
]
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', user_agents[randomint])]
response = opener.open(url)
the_page = response.read()
return hashlib.sha224(the_page).hexdigest()
current_hash = getHash() # Get the current hash, which is what the website is now
while 1: # Run forever
if getHash() == current_hash: # If nothing has changed
print
"Not Changed"
else: # If something has changed
email = 'myaddress@gmail.com' # Your email
password = 'password' # Your email account password
send_to_email = 'sentoaddreess@gmail.com' # Who you are sending the message to
message = 'This is my message' # The message in the email
server = smtplib.SMTP('smtp.gmail.com', 587) # Connect to the server
server.starttls() # Use TLS
server.login(email, password) # Login to the email server
server.sendmail(email, send_to_email, message) # Send the email
server.quit() # Logout of the email server
break
time.sleep(sleeptime)
解决方案
当我运行此代码时,输出是:进程以退出代码 0 完成。
好吧,这通常意味着脚本已被正确执行,但由于您是从 PyCharm 运行它,所以我不能多说。而是从命令行运行脚本,你会发现会发生什么。
我是 Python 的初学者,有什么问题吗?
好吧,您的代码没有任何明显的错误会阻止它运行,但是它的编写方式对调试没有帮助(稍后会详细介绍)。它可能有一个逻辑错误(同上)。
这是一个稍作修改(但功能相同)的版本:
import smtplib
try:
import urllib.request as urllib2
except ImportError:
import urllib2
import hashlib
import random
import time
# mail config
smtp_server = 'smtp.gmail.com'
smtp_port = 587
smtp_login = 'myaddress@gmail.com' # Your email
smtp_password = 'password' # Your email account password
recipient_email = 'sentoaddreess@gmail.com' # Who you are sending the message to
# url to be scraped
url = "https://www.off---white.com/en/IT/men/products/blue-af1-mca#"
# time between checks in seconds
sleeptime = 60
user_agents = [
'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
'Opera/9.25 (Windows NT 5.1; U; en)',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.142 Safari/535.19',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:8.0.1) Gecko/20100101 Firefox/8.0.1',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.151 Safari/535.19'
]
def get_random_agent():
return random.choice(user_agents)
def get_page(url):
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', get_random_agent())]
response = opener.open(url)
content = response.read()
response.close()
return content
def get_hash(url):
page = get_page(url)
return hashlib.sha224(page).hexdigest()
def sendmail(message):
server = smtplib.SMTP(smtp_server, smpt_port)
server.starttls()
server.login(smtp_login, smtp_password)
server.sendmail(smtp_login, recipient_email, message)
server.quit()
def main():
current_hash = get_hash(url)
while True: # Run forever => well, nope... cf below
time.sleep(sleeptime)
if get_hash(url) = current_hash:
print("Not Changed")
continue
print("changed, sending mail")
sendmail("has changed")
break # really ??? This means that you exit the loop here !
# this allow to use the script as either a script (python yourscript.py) or module
# so you can import it in a Python shell and test functions in isolation
if __name__ == "__main__":
main()
如您所见,我将逻辑拆分为小函数,并将主循环包装在一个main()
函数中,该函数仅在文件用作脚本(> python yourfile.py
在命令行上)时执行。这允许您在 python shell 中将脚本作为模块导入(不触发主函数)并单独测试函数,即:
bruno@blookup-MS-7982:~/Work/playground$ python
Python 2.7.15+ (default, Jul 9 2019, 16:51:35)
[GCC 7.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import somail
>>> somail.get_hash(somail.url)
'adc545b6e40da7b9a4c1319a933b7921e21f7877a03080ec720c71c9'
>>>
如何像 24/24 一样运行此代码?
好吧,首先您可能要对循环break
中的语句三思而后行。while
如果您希望您的代码“永远运行”,您不想退出循环,是吗?-)
一旦解决了这个问题,你的循环确实会“永远运行”——或者更准确地说,直到由于任何原因(站点关闭、网络错误、smtp 错误等)出现故障,因为你的错误处理完全为零——但这实际上比错误处理做得不好,因为至少你会有错误消息和完整的回溯告诉你出了什么问题,所以你知道你必须处理哪些异常以及在哪里处理它们。
现在它仍然需要您启动程序(从命令行或其他方式)并让进程运行- 如果您终止终端,这也会终止脚本。
现在有一些方法可以从 shell 中“分离”一个进程,但这是特定于系统的(在 linux/unices 上,它们被命名为“守护进程”,在 Windows 上它们被命名为“服务”IIRC),这本身就是一个完整的问题。
我会收到电子邮件吗?(显然我的地址、密码等中有我的信息)。
呃……我们怎么知道您是否收到了电子邮件?-)
话虽如此,我们真正能知道的是,如果脚本执行没有错误,至少 SMTP 服务器接受了邮件。那么消息会发生什么,没有人知道(直到,可能有人在他的邮箱中找到它)。
好像什么都没发生...
您的原始代码仅在没有任何更改时提及。当检测到更改时,它不会提供任何反馈。跟踪代码执行的第一个简单的简单方法是使用print
语句为您的代码添加趣味,这样您就可以直接看到它在做什么(生产代码将使用适当的日志记录)。测试代码的第二件事就是我所做的:将其分割成小的、集中的函数(每个函数只做一件事),然后从 python shell 测试你的函数。
下一步(双关语)是在步进调试器下运行您的代码,但这也太宽泛了。但这仍然是必备技能...
推荐阅读
- c - error: 'fscanf' 用于将字符串转换为整数值,但函数不会报告转换错误;考虑改用“strtol”
- javascript - 将价值从一个对象转移到另一个对象
- java - 未在 Searchview 中显示正确的 Listview 项目
- reactjs - React.js 在同一个按钮中排序 asc 和 desc
- java - 错误 500 - 当 java 代码尝试在 NetBeans 中调用 servlet 时,实例化 servlet 类时出错
- xml - 如何提取元数据字段的语言
- node.js - Next js 嵌套动态路由:通过 getstaticprops 获取数据并在路由之间共享数据
- ubuntu - 无法在 ubuntu 20.04 中安装 g++ 和 build-essentials
- java - 当两个相同的类具有相同的名称、包和内容时,如何解决类转换异常?
- sql - 在不提供日期的情况下获取sql中日期列中月份的第一天