天天看點

程式員的浪漫:晨起給女友定時發送天氣預報,睡前給女友定時講故事

情侶之間除了平日一起探究有趣的事情,總是少不了就是 “日常早晚請安”

1、請安情景一

男: 今日陽光明媚,多雲轉晴,小懶豬快起床啦

女:早起啦,話說你是不是還在被窩裡呢

男:嘿嘿

2、請安情景二

女:哎呀,挺晚了呢,早點休息吧,晚安

男:晚安

女:麼麼哒

一分鐘後。。。

女:快說,你是不是還在扣手機呢

男:嘿嘿

另外你的小可愛有沒有要求你每晚給她講故事,無奈故事庫那是相當匮乏!那可不可以讓聊天更智能一些呢!于是懶惰的程式員學會了爬蟲,嗯就是在網頁上會爬的蟲,下面介紹通過爬蟲~實作定時的早晚安,告别手動,人工智能!

一、早安,天氣預報

使用python的第三方子產品itchat實作早安問候,itchat是個基于網頁版微信的python微信API。功能目前做到基本可以滿足正常的消息收發,資訊的擷取等等。itchat的詳細介紹和使用可參加官網:itchat

話不多說直接給出程式源碼,下面天氣是從中國天氣官網上擷取的北京市海澱區的天氣,如果是其他地區可更換網址,:

from urllib.request import urlopen
from bs4 import BeautifulSoup
import itchat as ic
import time
import re

def getWeather():
    # 使用BeautifulSoup擷取天氣資訊
    resp=urlopen('http://www.weather.com.cn/weather/101010200.shtml')
    soup=BeautifulSoup(resp,'html.parser')
    tagDate=soup.find('ul', class_="t clearfix")
    dates=tagDate.h1.string
    tagToday=soup.find('p', class_="tem")
    try:
        temperatureHigh=tagToday.span.string
    except AttributeError as e:
        temperatureHigh=tagToday.find_next('p', class_="tem").span.string
    temperatureLow=tagToday.i.string
    weather=soup.find('p', class_="wea").string
    tagWind=soup.find('p',class_="win")
    winL=tagWind.i.string
    content = '早上好,小寶!\n 今日分海澱區天氣請注意查收:\n' + '今天是:' + dates + '\n' + '風級:' + winL + '\n' + '最低溫度:' + temperatureLow + '\n' + \
               '最高溫度:' + temperatureHigh + '\n' + '天氣:' + weather + '\n'
    return content


def main():
    try:
        message = getWeather()
        print('成功擷取天氣資訊')
    except:
        message = ""
        print("擷取天氣資訊失敗")
    # 參數hotReload=True實作保持微信網頁版登陸狀态,下次發送無需再次掃碼
    ic.auto_login(hotReload=True)
    users = ic.search_friends(name = '手動打碼')
    userName = users[0]['UserName']
    ret = ic.send(msg = message, toUserName = userName)
    if ret:
        print("成功發送")
    else:
        print("發送失敗")
    time.sleep(60)
    ic.logout()


if __name__ == '__main__':
    main()
           

二、午安,每日一練

每天督促女友和自己學習也是十分重要的,下面便是通過python的wxpy子產品實作給女友定時發送金山詞霸每日一練的原文和翻譯,wxpy子產品的詳細介紹和使用可參見官網:wxpy,代碼呈上:

from __future__ import unicode_literals
from threading import Timer
from wxpy import *
import requests
import random

# 設定cache_path=True, 保持微信登陸狀态
bot = Bot(cache_path=True)
# linux執行登陸請調用下面的這句
# bot = Bot(console_qr=2,cache_path="botoo.pkl")
def get_news():
    # 擷取金山詞霸的每日一句的英文和翻譯
    url = "http://open.iciba.com/dsapi/"
    r = requests.get(url)
    content = r.json()['content']
    note = r.json()['note']
    return content, note
 
def main():
    try:
        contents = get_news()
        # 你朋友的微信名稱,不是備注,也不是微信帳号
        my_friend = bot.friends().search('手動打碼')[0]
        my_friend.send(contents[0])
        my_friend.send(contents[1])
        my_friend.send(u"小寶,每日一練開始了!")
        # 每86400秒(1天),發送1次
        t = Timer(86400, send_news)
        # 通過生成随機數,使得每次發送的時間不固定
        ran_int = random.randint(0,100)
        t = Timer(86400+ran_int,send_news)
        t.start()
    except:
        my_friend.send(u"今日消息發送失敗了")
 
if __name__ == "__main__":
    main()
           

三、晚安,睡前講故事

哈哈,睡前小故事不用愁,爬蟲讓睡前故事無窮無盡!上面兩種方式都是微信定時發送,下面給出不同的方式,發送小故事到親愛的郵箱,每日郵箱踩一踩:

import requests
from bs4 import BeautifulSoup
import smtplib
from email.mime.text import MIMEText
import random
import time

def parse_html(url, headers):
    try:
        r = requests.get(url, headers=headers, timeout=60)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        html_content = r.text
        return html_content
    except:
        return "爬取失敗"


def parse_link(urllist, html):
    url_baisc = 'http://www.tom61.com/'
    soup = BeautifulSoup(html, 'html.parser')
    temp = soup.find('dl', attrs={'class': 'txt_box'})
    link_list = temp.find_all('a')
    for link in link_list:
        urllist.append(url_baisc + link.get('href'))


def sendemail(url, headers):
    # 發送方郵箱
    msg_from = '手動打碼'
    # 填入發送方郵箱的授權碼,不是密碼,如使用網易郵箱,需要到網易郵箱裡申請
    passwd = '手動打碼'
    # 接收方郵箱
    receivers = ['手動打碼']
    # 郵件主題
    subject = '小寶,今日份的睡前小故事,請查收'

    # 下面爬取首頁面故事内容
    html_content = parse_html(url, headers)
    text = []
    soup = BeautifulSoup(html_content, 'html.parser')
    temp = soup.find('div', class_='t_news_txt')
    for one in temp.findAll('p'):
        text.append(one.text)
    content = "小寶,今晚開始講故事喽:\n\n" + "\n".join(text)

    # 配置發送郵件資訊
    msg = MIMEText(content)
    msg['Subject'] = subject
    msg['From'] = msg_from
    msg['To'] = ','.join(receivers)
    try:
        # 郵件伺服器及端口号,不同郵箱會有不同
        s = smtplib.SMTP_SSL("smtp.163.com", 465)
        s.login(msg_from, passwd)
        s.sendmail(msg_from, msg['To'].split(','), msg.as_string())
        print("發送成功")
    except:
        print("發送失敗")
    finally:
        s.quit()


def main():
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
        }
    # 設定時間,保證明天發送不同的故事
    initial_time = time.mktime(time.strptime('2019-03-19', "%Y-%m-%d"))
    today = time.strftime('%Y-%m-%d', time.localtime(time.time()))
    timeArray = time.strptime(today, "%Y-%m-%d")
    now_time = int(time.mktime(timeArray))
    html_idx = int((now_time - initial_time) // 86400)

    url_list = []
    url = 'http://www.tom61.com/s/aiqinggushi/'
    html_content = parse_html(url, headers)
    parse_link(url_list, html_content)
    print("爬取故事連結完成")
    if html_idx < len(url_list):
        sendemail(url_list[html_idx], headers)
    else:
        print('該頁面故事網址以結束,請更換!')


if __name__ == '__main__':
    main()
           

四、crontab,定時任務

如何讓程式定時爬起來呢,可以使用crontab指令,使用crontab可以在指定的時間執行腳本或者一系列Linux指令。例如系統管理者安排一個備份任務使其每天都運作,這樣便可以實作每日定時的消息發送了。首先你需要在伺服器上安裝crontab,cron 是linux的内置服務,但它不自動起來,可以用以下的方法啟動、關閉這個服務:

/sbin/service crond start : 啟動服務

/sbin/service crond stop : 關閉服務

/sbin/service crond restart : 重新開機服務

/sbin/service crond reload : 重新載入配置

crontab常用指令有:

crontab –e : 修改 crontab 檔案. 如果檔案不存在會自動建立。

crontab –l : 顯示 crontab 檔案。

crontab -r : 删除 crontab 檔案。

crontab -ir : 删除 crontab 檔案前提醒使用者。

crontab檔案中指令書寫規則,下面給出crontab 檔案的書寫格式:

{minute} {hour} {day-of-month} {month} {day-of-week} {full-path-to-shell-script} 
minute: 區間為 0 – 59 
hour: 區間為0 – 23 
day-of-month: 區間為0 – 31 
month: 區間為1 – 12. 1 是1月. 12是12月. 
Day-of-week: 區間為0 – 7. 周日可以是0或7.

Crontab 示例
1. 在 12:01 a.m 運作,即每天淩晨過一分鐘。這是一個恰當的進行備份的時間,因為此時系統負載不大。
1 0 * * * /root/bin/backup.sh

2. 每個工作日(Mon – Fri) 11:59 p.m 都進行備份作業。
59 11 * * 1,2,3,4,5 /root/bin/backup.sh
or
59 11 * * 1-5 /root/bin/backup.sh

3. 每5分鐘運作一次指令
*/5 * * * * /root/bin/check-status.sh

4. 每個月的第一天 1:10 p.m 運作
10 13 1 * * /root/bin/full-backup.sh

5. 每個工作日 11 p.m 運作。
0 23 * * 1-5 /root/bin/incremental-backup.sh
           

懶惰的程式員快行動起來吧,附上不知在哪裡看到的專屬程式員的情詩一首,專心做程式員屆的僞文青:

世界上最遙遠的距離

不是生與死的距離

是你在if我在else

雖然時常一起出現

但永遠不會結伴執行

感謝try-catch

讓我有機會成為你的finally

守在這必經的渡口

繼續閱讀