大数据

使用python+微博进行远程关机

很长一段时间没有更新简书的内容了,打算把微博爬虫完善得差不多之后,再系统的把做微博爬虫的每个模块和阶段都记录下来。其中微博页面抓取和解析、用户页面抓取和分析等模块,都是可以复用的。现在还只是单机单线程,因为微博的反爬虫机制还没完全研究透,等找到抓取的阈值后再考虑分布式或者多进程。这里是微博扩散分析的项目地址,有兴趣的可以看看,喜欢的话不防点个star,如何?


这篇文章写的是基于模拟登陆微博的一个小工具。使用情况是人不在办公室,但是电脑没有关闭,需要远程关闭电脑。对模拟登陆微博有问题的同学,请移步我的这篇文章。下面进入正题。

思路

  • 定时模拟登陆(定时是因为微博cookie24小时失效),关于模拟登陆详细步骤可参考我的博文,代码可参考github项目
  • 定时(10分钟)获取最新一条微博,并把发布时间和系统时间做比较,如果相差在半个小时以内,我们就认为命令有效,那么就让系统执行关机命令

项目依赖

  • 模拟登陆+页面解析:
    • requests+pyexecjs+beautifulsoup
    • pip install requests
    • pip install bs4
    • pip install PyExecJS
  • 命令行解析docopt
    • pip install docopt
  • phantomjs
    • windows:在phantomjs官网下载它,并且把它的路径添加到环境变量
    • ubuntu:sudo apt-get install phantomjs 或者到官网下载并且添加到环境变量

各个模块和代码

login.py

该模块代码负责模拟登陆,之前已经详细讲过这部分代码了,在这里就不啰嗦了,最后返回的是session和uid(微博ID,用于拼凑主页URL)

weibo_parser.py

解析微博主页,并且返回最新一条微博和发布时间

具体代码如下

 def get_newest(session, uid):
# 获取只含有原创内容的个人主页
url = 'http://weibo.com/' + uid + '/profile?profile_ftype=1&is_ori=1#_0'
page = session.get(url).text
soup = BeautifulSoup(page, 'html.parser')
scripts = soup.find_all('script')
status = ' '
for s in scripts:
if 'pl.content.homeFeed.index' in s.string:
status = s.string
#用正则表达式获取微博原创内容
pattern = re.compile(r'FM.view((.*))')
rs = pattern.search(status)
if rs:
cur_status = rs.group(1)
html = json.loads(cur_status).get('html')
soup = BeautifulSoup(html, 'html.parser')
# 获取最新一条微博所有信息
newest = soup.find(attrs={'action-type': 'feed_list_item'})
# 获取最新发布内容
post_cont = newest.find(attrs={'node-type': 'feed_list_content'}).text.strip()
# 获取最新发布时间
post_stamp = int(newest.find(attrs={'node-type': 'feed_list_item_date'}).get('date')[:-3])
post_time = datetime.fromtimestamp(post_stamp)
now = datetime.now()
# 计算此刻和发布时间的时间差(单位为秒)
t = (now - post_time).total_seconds()
return post_cont, t
else:
return None

这里面用到的知识包括beautifulsoup和正则表达式,它们的具体使用我就不细说了,关于正则表达式,search()函数我是用得最多的,beautifulsoup我用得最多的是find(attrs={key: value}),attrs这个参数真心好用!这个是beautifulsoup的官方文档:bs中文文档.关于页面解析,可能我会专门写一篇文章详细说,这里就略去了。

pc_shutdown.py

"""Resolvewang
Usage:
pc_shutdow.py name password
pc_shutdow.py (-h | --help)
pc_shutdow.py --version
Options:
-h --help Show this screen.
--version Show version
"""
from login import get_cur_session
from weibo_parser import get_newest
from docopt import docopt
from os import system
import platform
import time
def shutdown(name, password):
session, uid = get_cur_session(name, password)
return get_newest(session, uid)
if name == 'main':
# 从命令行获取登陆账号和密码
args = docopt(doc, version='ShutdownMyPC 1.0')
login_name = args.get('')
login_pass = args.get('')
# 循环用于定时查看是否有新微博发布
while True:
# 获取发布内容和时间,内容用 " "隔开,比如“关机 10”
cont, ptdelta = shutdown(login_name, login_pass)
info = cont.split(' ')
# 判断是关机命令还是正常微博
if info[0] == '关机' and ptdelta < 30 60:
shut_time = 0
try:
shut_time = int(info[1])
except Exception:
print('马上自动关机')
else:
print('{time}分钟后自动关机'.format(time=info[1]))
finally:
# 判断操作系统平台,由于没有mac实验环境,所以这里没添加mac的相关判断
os_system = platform.system().lower()
if os_system == 'windows':
command = 'shutdown -s -t {shut_time}'.format(shut_time=shut_time
60)
else:
command = 'shutdown -h {shut_time}'.format(shut_time=shut_time)
# 执行关机命令
system(command)
time.sleep(10*60)

这段代码的逻辑基本都写在注释里了,其中有个docopt模块,是关于命令行参数的,如果有不清楚的同学可以看看这篇博客,也可以看看它的github,里面有很多例子


关于使用微博进行远程关机的讲解都完了,上述代码还有可以改进的地方,特别是pc_shutdown.py,比如

  • 使用定时器进行查看新微博
  • session复用直到24小时失效,这样就不用每隔十分钟就重新登陆一次了,可以通过多进程或者多线程共享变量实现
  • 可以把这个小工具修改成一个开机启动脚本(linux平台)或者服务(win平台)。

吾生也有涯,而知也无涯。大家加油,共勉!