作者:miaoo

1.应用场景

由于自己做的一个系统需要用到发送短信到自己手机的功能,于是搜索了一下,发现了一个通过移动飞信通道发送短信开源库:PyFetion

PyFetion 模拟实现了飞信的通信协议,所以能够实现的功能非常多:短信收发、好友管理、修改状态等等等。

但是,由于我只需要发送短信,所以其它功能都很多余;再加上使用PyFetion 登录飞信时可能需要输入验证码,所以不太适合自动化系统的调用。

继续搜索发现了飞信为手机用户提供了一个wap站点:http://f.10086.cn

PS:由于是这一个wap站点,您可能需要在FireFox中安装扩展(Extension):wmlbrowser ,以便正常的浏览.

通过它能够进行在线信息收发。由于wap站点代码结构比较简单,所以很适合用程序模拟用户登录、发送信息的整个流程,以达到发送短信的目的。

2.代码分析

代码主要用到了下面几个lib

  1. cj = cookielib.LWPCookieJar()
  2. opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
  3. urllib2.install_opener(opener)

登陆时,首先要处理Cookie信息

  1. cj = cookielib.LWPCookieJar()
  2. opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
  3. urllib2.install_opener(opener)

其次,我们在登录界面填写手机号及密码后,点击登录按钮,浏览器会通过POST方法向服务器提交登录信息以便验证身份。用Firefox的Httpfox插件可以抓包查看浏览器提交的数据内容:

可以看到,在点击登录后浏览器发送POST 请求提交登录数据,其中:pass 为密码,loginstatus为登录状态(4表示隐身),m为手机号码。我们在python中定义一个字典类型变量记录要模拟提交的数据:

  1. parameter = {
  2. 'pass':‘你的密码’,
  3. 'm':'你的手机号',
  4. 'loginstatus':4
  5.  
  6. }

然后,生成POST请求,并发送:

  1. url_login = 'http://f.10086.cn/im/login/inputpasssubmit1.action'
  2. req = urllib2.Request( #生存POST请求
  3. url =url_login ,
  4. urllib.urlencode(parameter)
  5. )
  6. jump = urllib2.urlopen(req) #发送请求

在提交登录请求后,服务器回返回一个跳转页面,其中包含一个跳转连接(URL),如果登录成功,则返回:

  1. /im/index/indexcenter.action?t=xxxxxxxxxxxxxxxxx

其中xxx代表一串数字。如果登录失败,则返回先前的登录页:

  1. /im/login/login.action

我们用正则表达式在页面中提取出这个链接,判断登录是否成功(关于正则表达式的内容,推荐:正则表达式30分钟入门教程):

  1. page = jump.read();
  2. #获取跳转链接
  3. url = re.compile(r'id="start".*?ontimer="(.*?);').findall(page)[0]
  4. if url == '/im/login/login.action':
  5. print 'Login Failed!' #登录失败
  6. raw_input('Press any key to exit.')
  7. return
  8. else:
  9. print 'Login Successfully!' #登录成功

同时,我们也将连接尾部那一串数字参数提取出来,以备待会儿使用:

  1. arg_t = re.compile(r't=(d*)').findall(page)[0] #获取参数

同样的方法,我们可以抓包提取到发送短信时POST的数据内容,并用程序模拟提交:

  1. url_sendmsg = 'http://f.10086.cn/im/user/sendMsgToMyselfs.action'
  2. sendmsg = urllib2.Request(
  3. url =url_sendmsg,
  4. urllib.urlencode('msg':‘你要发送的消息’.decode('gbk').encode('utf-8'))
  5. )
  6. res = urllib2.urlopen(sendmsg)

通过提交POST请求后返回的连接判断发送是否成功:

  1. if res.geturl == 'http://f.10086.cn/im/user/sendMsgToMyself.action' :
  2. print 'Send Failed!'
  3. else:
  4. print 'Send Successfully!'

最后注销退出:

  1. logout = urllib2.Request(url_logout + arg_t)
  2. response = urllib2.urlopen(logout)
  3. print 'Logout Successfully!'

完整的代码可以看下面。整个代码共45行,在Python 2.7下编译通过。

3.改进

目前只实现了发送短信到自己手机的功能(当然,这就是我目前所需要的),其实,我们在完成登录操作后,便能够提取出好友列表,用上文类似的方法就能够给任意的飞信好友发送短信了。这个功能留到以后需要的时候再完成吧。

4.总结

本文主要使用了:

  1. urllib2.Request(xxx)
  2. urllib2.urlopen(xxx)

可以看到,在python中使用urllib2可以很方便的进行各种网页相关的交互操作,如页面抓取、表单提交等等,再配合正则表达式,可以构造出各种有趣的应用。

完整代码:

  1. # -*- coding: utf-8 -*-
  2. import cookielib
  3. import urllib
  4. import urllib2
  5. import re
  6.  
  7. url_login = 'http://f.10086.cn/im/login/inputpasssubmit1.action'
  8. url_logout = 'http://f.10086.cn//im/index/logoutsubmit.action?t='
  9. url_msg = 'http://f.10086.cn/im/user/sendMsgToMyselfs.action'
  10. user = 'Your Phone Number'
  11. password = 'Your Passwrdd'
  12. loginstatus = '' #��¼״̬,4��ʾ����
  13. arg_t = ''
  14.  
  15. def fetion(msg):
  16. cj = cookielib.LWPCookieJar()
  17. opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
  18. urllib2.install_opener(opener)
  19. args = {'pass':password, 'm':user,'loginstatus':loginstatus}
  20. print 'Logining...'
  21. req = urllib2.Request(url_login, urllib.urlencode(args))
  22. jump = opener.open(req)
  23. page = jump.read();
  24. url = re.compile(r'<card id="start".*?ontimer="(.*?);').findall(page)[0] #��ȡ��ת����
  25. arg_t = re.compile(r't=(\d*)').findall(page)[0]
  26. if url == '/im/login/login.action': #��¼ʧ��
  27. print 'Login Failed!'
  28. raw_input('Press any key to exit.')
  29. return
  30. else:
  31. print 'Login Successfully!'
  32. sendmsg = urllib2.Request(url_msg, urllib.urlencode({'msg':msg.decode('gbk').encode('utf-8')}))
  33. finish = urllib2.urlopen(sendmsg)
  34.  
  35. if finish.geturl == 'http://f.10086.cn/im/user/sendMsgToMyself.action' :
  36. print 'Send Failed!'
  37. else:
  38. print 'Send Successfully'
  39. logout = urllib2.Request(url_logout + arg_t)
  40. response = urllib2.urlopen(logout) #ע��
  41. print 'Logout Successfully!'
  42. #print response.read().decode('utf-8').encode('gbk')
  43.  
  44. msg = raw_input('what do you want to say:')
  45. fetion(msg)

使用python移动飞信模块发送短信的更多相关文章

  1. Linux-C实现GPRS模块发送短信

    “GSM模块,是将GSM射频芯片.基带处理芯片.存储器.功放器件等集成在一块线路板上,具有独立的操作系统.GSM射频处理.基带处理并提供标准接口的功能模块.GSM模块根据其提供的数据传输速率又可以分为 ...

  2. python每天定时发送短信脚本

    最近业务上需要每天解析txt文本或者excel文件,读取内容发送短信,发送的时间段可控,用python实现 安装pip依赖 pip install -r requirement.txt xlrd Py ...

  3. MonkeyRunner执行Python脚本实例——发送短信增强版

    很久之前就写好的了,准备写个自动执行Monkey的脚本时才想到去找它,还是写在博客里找起来方便. 这次更新了批处理自动连接设备后执行Py脚本,结构如下图: 其中shotscreen为存放截图文件夹,s ...

  4. 使用Python往手机发送短信(基于twilio模块)

    官网是https://www.twilio.com twilio的一句话介绍——提供SDK帮你连接世界上所有人,你可以很方便的调用他们提供的接口来给指定手机发短信,打电话. 首先在twilio的官网注 ...

  5. 注册登录页面修订-Python使用redis-手机验证接口-发送短信验证

    登录页面修订 views.Login.vue <template> <div class="login box"> <img src="@/ ...

  6. Python发送短信提醒

    Python发送短信可借助腾讯云平台提供的短信服务 发送短信需要的及格参数: 1.SDK_AppID和SDK_Key 2.签名: 3.模板ID 下面贴出源码DEMO: from qcloudsms_p ...

  7. 使用 Python 发送短信?

    上回食行生鲜签到,我们说到怎么把签到结果发出来,于是就找到了 Twilio. Twilio 是一个位于加利福尼亚的云通信(PaaS)公司,致力于为开发者提供通讯模块的 API.由于 Twilio 为试 ...

  8. 利用python库twilio来免费发送短信

    大家好,我是四毛,最近开通了个人公众号“用Python来编程”,欢迎大家“关注”,这样您就可以收到优质的文章了. 今天跟大家分享的主题是利用python库twilio来免费发送短信. 先放一张成品图 ...

  9. 调用 url_launcher 模块打开外部浏 览器 打开外部应用 拨打电话 发送短信

    1.Flutter url_launcher 模块    Flutter url_launcher 模块可以让我们实现打开外部浏览器.打开外部应用.发送短信.拨打电话等功能.    https://p ...

随机推荐

  1. [RxJS] Implement pause and resume feature correctly through RxJS

    Eventually you will feel the need for pausing the observation of an Observable and resuming it later ...

  2. Batch Normalization 反向传播(backpropagation )公式的推导

    What does the gradient flowing through batch normalization looks like ? 反向传播梯度下降权值参数更新公式的推导全依赖于复合函数求 ...

  3. 关于用strace工具定位vrrpd进程有时会挂死的bug

    只做工作总结备忘之用. 正在烧镜像,稍总结一下进来改bug遇到的问题. 一个项目里要用到L3 switch的nat,vrrp功能,但实地测试中偶然出现write file挂死的情况,但不是必现.交付在 ...

  4. thinkphp5 tp5 获取模块名控制器名方法名

    <?php namespace app\index\controller; use think\Db; use think\Controller; class Base extends Cont ...

  5. UE4 Editor快捷键(ShortCut Key)

    转载请注明出处,所有权利保留. Unreal Engine4的快捷键现在无官方文档,因为他们工作比较忙啊. 记录时间:2014-10-15 现在自己整理一个,仅供参考. 因为他们的team成员说的还有 ...

  6. static,const,extern,以及全局常量

    1:全局常量的定义:1:创建Header头文件,再创建与Header头文件类名相同的空文件作为.m文件,.h文件引用文件,.m文件负责定义常量 #import <UIKit/UIKit.h> ...

  7. Django之settings.py 的media路径设置

    在一个 models 中使用 FileField 或 ImageField 需要以下步骤: 1. 在你的 settings.py文件中, 定义一个完整路径给MEDIA_ROOT 以便让 Django在 ...

  8. 【47.95%】【codeforces 554C】Kyoya and Colored Balls

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  9. 从多路搜索树到 B-树

    1. 什么是 B 树 B 树是为磁盘或其他直接存取的辅助存储设备而设计的一种平衡二叉树: B 树类似于红黑树,但它们在降低磁盘 I/O 操作数方面要更好一点, 许多数据库系统使用 B 树或者 B 树的 ...

  10. 【转载】FormsAuthenticationTicket 对象

    1.使用Forms验证存储用户自定义信息 Forms验证在内部的机制为把用户数据加密后保存在一个基于cookie的票据FormsAuthenticationTicket中,因为是经过特殊加密的,所以应 ...