|
本帖最后由 jackwmj12 于 2017-4-23 09:22 编辑
之前一直想用树莓派来做自己的数据库,但是苦于没法外网访问,然后利用免费的花生壳,又对流量有所限制。所以自己想了个别的办法来获取自己家里的树莓派的公网ip,获取IP我这里有两个阶段,第一个阶段是我树莓派通过花生壳建立一个网页,这个网页什么都不干,就返回一个IP地址,该返回的IP地址取值于树莓派服务器的数据库。第二阶段是树莓派还会讲IP发送到你指定的邮箱和地址。所以我们要做的就是让树莓派跑一个脚本,这个脚本的功能就是运行一个爬虫,访问访问 http://www.ip.cn/ ,或者http://members.3322.org/dyndns/getip,爬去该网页上显示的你的机器的公网IP,如果IP变更,那么就将你树莓派上数据库里IP值变更掉,并且将IP发送到你的邮箱内。
这样,我们的树莓派公网IP我们就获得了,如果你在外网需要访问树莓派的服务器或者是ssh远程控制你的树莓派,那么只需要检查邮箱或者查看你的网页下显示的IP地址就可以了。当然这里有一个前提,那就是你需要用端口映射来设置路由器,将你路由器上的公网端口映射到你内网的树莓派上的IP地址
比如你需要使用3306号端口做mysql,那你就在路由器里设置本地ip:3306号端口映射到外网ip:3306号端口就可以直接用 外网:3306 进行访问。
#!/usr/bin/python3
#-*- coding:utf-8 -*-
import urllib.request
from smtplib import SMTP_SSL
from email.header import Header
from email.mime.text import MIMEText
import time
from email.parser import Parser
from email.header import decode_header
import poplib
import info_init
import pymongo
class Applaction:
def __init__(self):
info_app = info_init.Applaction()
# info_data=info_app.load_decode(file_path=r"E:\data_init.jason") #这个jason文件保存着你的资料
# self.url = info_data["url"]
self.url = r"http://members.3322.org/dyndns/getip"
self.email_head =info_data["email_head"] #email头,用于脚本自动从邮箱读取IP时筛选邮件
self.email_send =info_data["email_send"] #发送的邮箱号
self.email_sendpw=info_data["email_sendpw"] #发送邮箱密码
self.email_sendhost = info_data["email_sendhost"] #发送邮箱host
self.email_recv=info_data["email_recv"] #接收邮箱号
self.email_recvpw = info_data["email_recvpw"] #接受邮箱密码 #用于从邮箱读取IP信息
self.email_recvhost = info_data["email_recvhost"] #接受邮箱HOST
self.ip_url = "你树莓派显示IP的网站名"
user = info_data["mongo_user"] #数据库账号
pwd = info_data["mongo_pw"] #数据库密码
uri = 'mongodb://' + user + ":" + pwd + "@" + "localhost" + ":" + "27017"
client = pymongo.MongoClient(uri)
metal = client['金属价格']
coper = metal['coper']
self.mongo_ip = coper['ip']
def ip_check(self):
content = None
try:
content = self.mongo_ip.find()[0]["ip"]
except Exception as e:
print(e)
if content is None:
ip_address = 0
message =[]
# pop3服务器地址
host = self.email_recvhost
# 用户名
username = self.email_recv
# 密码
password = self.email_recvpw
# 创建一个pop3对象,这个时候实际上已经连接上服务器了
pp = poplib.POP3_SSL(host)
# 设置调试模式,可以看到与服务器的交互信息
#pp.set_debuglevel(1)
# 向服务器发送用户名
pp.user(username)
# 向服务器发送密码
pp.pass_(password)
# 获取服务器上信件信息,返回是一个列表,第一项是一共有多上封邮件,第二项是共有多少字节
ret = pp.stat()
num=ret[0]#ret[0]总共有几封邮件# 取第一封邮件完整信息,在返回值里,是按行存储在down[1]的列表里的。down[0]是返回的状态信息
while (ip_address is 0):
# ret = pp.list()
hdr,lines,octet = pp.retr(num)
try:
for line in lines:
message.append(line.decode('utf-8'))
msg_content = '\r\n'.join(message)
msg = Parser().parsestr(msg_content)
except Exception as e:
print(e)
num = num -1
if (num is 0):
pp.quit() #退出pop
return None
try:
ip_flag = (self.decode_str(msg.get('Subject')))#获取主题
if self.email_head in ip_flag:#获取树莓派IP
ip = ip_flag.split(':')#字符分割
ip_address = ip[1] #获取ip地址
return ip_address
else :
del message[:]
except Exception as e:
print(e)
pp.quit()
return content
def ip_crawler(self):
try: # 伪装头,用于防止网站服务器屏蔽你的ip
req = urllib.request.Request(self.url, headers={
'Connection': 'Keep-Alive',
'Accept': 'text/html, application/xhtml+xml, */*',
'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
})
wp = urllib.request.urlopen(req)
content = wp.read()
content = content.decode('utf-8', 'ignore') # utf-8解码
# content = content[content.find("IP:") + 1:] # 抓取ip所在位置
# content = content[content.find("<code>") + 6:content.find("</code>")] # 抓取ip
return content
except Exception as e:
print(e)
return None
def send_email(self,content):
mail_info = {
"from": self.email_send,
"to": self.email_recv,
"hostname": self.email_sendhost,
"username": self.email_send,
"password": self.email_sendpw,
"mail_subject": '%s:%s' % (self.email_head, content),
"mail_text": "%s" % content,
"mail_encoding": "utf-8"
}
# 这里使用SMTP_SSL就是默认使用465端口
smtp = SMTP_SSL(mail_info["hostname"])
smtp.set_debuglevel(1)
try:
smtp.ehlo(mail_info["hostname"])
smtp.login(mail_info["username"], mail_info["password"])
msg = MIMEText(mail_info["mail_text"], "plain", mail_info["mail_encoding"])
msg["Subject"] = Header(mail_info["mail_subject"], mail_info["mail_encoding"])
msg["from"] = mail_info["from"]
msg["to"] = mail_info["to"]
smtp.sendmail(mail_info["from"], mail_info["to"], msg.as_string())
smtp.quit()
return True
except Exception as e:
print(e)
return False
def decode_str(self,s): #邮件格式转换
value, charset = decode_header(s)[0]
if charset:
value = value.decode(charset)
return value
def ip_update(self,data):
print("IP更新为{}".format(data))
self.mongo_ip.update({'num': '0'}, {'$set': {'ip':data}})
def ip_get(self):
content = None
try:
wp = urllib.request.urlopen(self.ip_url)
content = wp.read()
content = content.decode("UTF-8").split(":")[1].strip()
except Exception as e:
print(e)
if content is None:
ip_address = 0
message = []
# pop3服务器地址
host = self.email_recvhost
# 用户名
username = self.email_recv
# 密码
password = self.email_recvpw
# 创建一个pop3对象,这个时候实际上已经连接上服务器了
pp = poplib.POP3_SSL(host)
# 设置调试模式,可以看到与服务器的交互信息
# pp.set_debuglevel(1)
# 向服务器发送用户名
pp.user(username)
# 向服务器发送密码
pp.pass_(password)
# 获取服务器上信件信息,返回是一个列表,第一项是一共有多上封邮件,第二项是共有多少字节
ret = pp.stat()
num = ret[0] # ret[0]总共有几封邮件# 取第一封邮件完整信息,在返回值里,是按行存储在down[1]的列表里的。down[0]是返回的状态信息
while (ip_address is 0):
# ret = pp.list()
hdr, lines, octet = pp.retr(num)
try:
for line in lines:
message.append(line.decode('utf-8'))
msg_content = '\r\n'.join(message)
msg = Parser().parsestr(msg_content)
except Exception as e:
print(e)
num = num - 1
if (num is 0):
pp.quit() # 退出pop
return None
try:
ip_flag = (self.decode_str(msg.get('Subject'))) # 获取主题
if self.email_head in ip_flag: # 获取树莓派IP
ip = ip_flag.split(':') # 字符分割
ip_address = ip[1] # 获取ip地址
return ip_address
else:
del message[:]
except Exception as e:
print(e)
pp.quit()
return content
if __name__ == '__main__':
content=None
content_email=None
ip_get =Applaction()
while True:
if content_email is None:
content_email = ip_get.ip_check()
print(content_email)
content = ip_get.ip_crawler()
print(content)
if ((content_email != content) and content_email != None and content != None):#如果新ip与已存在的老ip不一样,则发送邮件,反之不发
content_email =content
ip_get.send_email(content)
ip_get.ip_update(content)
elif content ==None:
time.sleep(60)
time.sleep(3600) |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|