用python进行外网对自己服务器访问(不需要花生壳)

之前一直想用树莓派来做自己的数据库,但是苦于没法外网访问,然后利用免费的花生壳,那稳定性实在不敢奉为。所以自己想了个别的办法来获取自己家里的树莓派的公网ip。

这里首先说明下实现的原理:在你的服务器上利用python爬虫,访问 http://www.ip.cn/ 网站,爬取该网站上显示的你机器的ip,然后将获得的ip发送到你的邮箱内,该程序每1分钟运行一次,那么久算公网ip改变也基本可以第一时间发到你邮箱。

另一端是你的客户端,只需要利用python的邮件模块去邮箱里抓取你的服务器ip地址的那一份邮件就可以获得你的服务器当前ip地址。

在这里你还需要做的一件事就是去你的路由器里设置端口映射,比如你需要使用3306号端口做mysql,那你就在路由器里设置本地ip:3306号端口映射到外网ip:3306号端口就可以直接用 外网:3306 进行访问。

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
from email.utils import parseaddr
import poplib
import re
import os, sys, string
import traceback
url ='http://www.ip.cn/'
#从邮箱内获取最近的一次ip,因为程序每五分钟执行一次,
# 所以需要确认该ip是否已经发送,没有发送才进行送。  已经发送的就不需要再发送
                                      
def  Ip_recv(name):         
    ip_address =0
    message =[]
    # pop3服务器地址
    host ="pop3.163.com"
    # 用户名
    username ="xxxxxx@163.com"
    # 密码
    password ="xxxxxxx"
    # 创建一个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:
            pass
        num = num -1
        if(numis0):
            pp.quit()#退出pop
            return0
        try:
            ip_flag = (decode_str(msg.get('Subject')))#获取主题
            #print ("检查邮件...")
            if  name  in  ip_flag:#获取树莓派IP
                ip = ip_flag.split(':')#字符分割
                ip_address = ip[1]#获取ip地址
                #print("取得IP成功.")
                return  ip_address
            else:
                del message[:]
        except:
            #print("取得IP失败,请检查邮箱")
            pass
    pp.quit()
def  decode_str(s):#邮件格式转换
    value, charset = decode_header(s)[0]
    if  charset:
        value = value.decode(charset)
    return  value

def get_local():
    ip_local =input("输入查询地址:1是home,2是company\n")
    ip_local=int(ip_local)
    if ip_local is 1:
        name ="RaspberryIP"#用于识别是家里的ip,还是公司的ip
    elif ip_local is 2:
        name ="CompanyIP"
    else:
        name=get_local()
    return name

if__name__ =='__main__':
    content_pre =0
    count =0
    name=get_local()#确认需要获取哪里的ip,如果单纯在树莓派上运行,
                                            #则直接把判断变成肯定就行
    print("name is %s"%name)
    while True:
        try:#伪装头,用于防止网站服务器屏蔽你的ip
            req = urllib.request.Request(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解码
            index =  content.find("IP:")#找到ip所在地
            content=content[content.find("IP:")+1:]#抓取ip所在位置
            #print(content)
            content=content[content.find("")+6:content.find("")]#抓取ip
        except:
        #print("get ip error")
            pass
        try:
            E_mail_ip=Ip_recv(name)#从邮箱里获取邮件里已有ip
        except:
            E_mail_ip = content
        if((content_pre != content)and(E_mail_ip != content)):
        #如果新ip与已存在的老ip不一样,则发送邮件,反之不发
            count =count+1
            content_pre =content
            mail_info = {
                "from":"yyyyyyy@qq.com",                          #你发送ip的邮箱
                "to":"xxxxxxxx@163.com",                          #你接受ip的邮箱
                "hostname":"smtp.qq.com",                       
                "username":"yyyyyyyyyy@qq.com",            #你接受ip的邮箱名
                "password":"yyyyy",                                     #接受ip邮箱的密码
                "mail_subject":'%s:%s'%(name,content),    #邮件主题
                "mail_text":"%s"%content,                          #ip地址
                "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()
                print(count)
            except:
                print("send email error")
                pass
        time.sleep(60)
#GBK,GB2312,Big5,utf-8
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,673评论 18 139
  • 作用:限制类型 为什么退出泛型:迎合swift 泛型的作用: 限制类型 提高代码的规范,减少沟通的成本 泛型的用法...
    Homer1ynn阅读 350评论 0 0
  • 当自由成为书写的前提,这是期待已久的事,但为何有些近情情却,提起笔所有的词汇在脑海中激荡但却在涌出的那刻拥塞了,或...
    茹小茹啊阅读 120评论 2 0
  • 我这个不是电影迷,但有时间却要去电影院小资一把的人,这次无意当中抢先观看了电影《一句顶一万句》。 看完之后感觉拍的...
    长毛兔呀阅读 1,309评论 3 5
  • 群里的伙伴估计大部分都到到家了,我却一个人在北京瞎耗,我发誓,这是我最后一次这么晚回家~ 之前错误了预估哈尔滨小伙...
    farewell兔too阅读 344评论 0 0