
前言
今天沒妹子約,剛好研究一下。如何用神奇的python打造一個把妹神器吧。看完這個,你們就能走向人生巔峰,迎娶白富美啦。
我知道你們想看看效果

當然啦,這只是測試版的效果,真正的版本可比這個厲害多啦。不過作為一個直男,另一個男的給小編發這個測試感覺還是有點怪怪的哈。
文:吉柏言
暑假來了,各位又不得不和男女朋友暫時分開2個月了!!長達兩個月的時間里不能相見,你可知我多想你啊,想知道你的城市下雨了嗎,想知道你帶傘了嗎,想知道你長什么樣,想知道你叫啥,咳咳,單身汪小編表示情緒穩定。
沒關系,雖然不能見面,但是雲關懷還是要到的嘛,每天查一查你那里的天氣如何,送上作為男朋友的關切問候,再配上一張愛你的圖片,噫~~。但是作為絕地雞王那必須每晚吃雞呀,早上醒來忘了打卡怎么辦?? 能讓機器干的活我們何必自己動手呢?當然可以走一波python大法好啦!
今天的代碼我們要做得就是定點打卡,每天向親愛的女票送去溫暖的祝福~~,單身汪小編表示情緒穩定。
環境准備
首先,安裝我們需要的庫:
import requests
from bs4 import BeautifulSoup
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header
import smtplib
import os
我們用requests + bs4 庫進行爬取當日的天氣狀況以及我們需要的圖片,用email庫和smtplib庫來發郵件,當中我們還需要os庫對其他文件進行操作。
開始搞事
首先爬取天氣狀況和圖片資源,我選擇的是對中國氣象台和豆瓣上一位名為名為“狼魄乾坤”的網友的豆瓣相冊進行爬取,首先本着盜亦有道的原則,先查看robots協議。


很好,中央氣象站沒有robots協議,豆瓣也沒有對相冊加以限制,那么我們可以放心大膽地爬取了。
進入網站,查找一下她所在的城市,本汪沒有女票就以自己所在的城市為例子了。
http://www.nmc.cn/publish/forecast/AHB/wuhan.html 。分析一下這個地址,發現對於城市的分類命名規則是A+省份簡寫如湖北(HB)以及城市拼音,對於一些比較模糊的省份簡寫小編附在下圖的代碼中:
def main():
# print("河北HE 內蒙古NM 陝西SN 黑龍江HL 河南HA")
# province = input("input the province,the big alpha for short:")
# city = input("input the city you wanna search plz:")
province = "HB"
city = "wuhan"
url = "http://www.nmc.cn/publish/forecast/A" + province + "/" + city + ".html"
html = getHTMLText(url)
url = "https://www.douban.com/photos/album/157693223/"
image = getHTMLText(url)
請忽略小編的辣雞英文。
getHTMLText(url)是自定義方法,為的是獲取網頁的源代碼,返回值為包含整個源代碼的字符串:
def getHTMLText(url):
try:
r = requests.get(url)
print(r.raise_for_status)
r.encoding = r.apparent_encoding
return r.text
except:
return ""
我們用requests.get(url)向網站提出爬取申請,用raise_for_status查看狀態碼,如果為200則說明爬取成功,然后我們用apparent_encoding替換掉encoding,這是讓程序自己識別編碼方式,保證返回的不是亂碼。倘若爬取過程沒有出錯,就把爬下來的新鮮的天氣信息素材返回給變量html。用同樣的方法,我們獲取新鮮的圖片庫的素材也用同樣的方法,返回給變量image。
imagLink = []
whetherInfo = parserHTMLWeather(html)
name = 1
for image in imagLink:
print(image)
for image in imagLink:
downloadPicture(image,name)
name += 1
回到main方法,我們要聲明一個imagLink的列表,用來存放每個圖庫中每個圖的地址,whetherInfo用來存儲解析后的html的信息。打印image確定地址返回無誤,因為在圖庫的源碼中有豆瓣自己的大圖地址和圖片的地址,我們需要的是圖片地址,確定無誤后就可以逐個進行下載圖片資源了。
先來看解析天氣信息的parserHTMLWeather方法:
def parserHTMLWeather(html):
try:
dirt = {}
soup = BeautifulSoup(html,"html.parser")
place = soup.find(name = "head").find("title")
dirt["place"] = str(place.string).split("-")[0]
AnnoceTime = soup.find(name = 'div', attrs = {"class":"btitle"}).find("span")
dirt["AnnoceTime"] = str(AnnoceTime.string)
Everyday = AnnoceTime.find_parent().find_next_sibling().find_all(name = "div",class_ = "detail")
for eachday in Everyday:
info = eachday.find(name = "div",class_ = "day")
thisDay = {}
date = str(info.find(name = "div",class_ = "date").string)
week = str(info.find(name = "div",class_ = "week").string)
wdesc = str(info.find(name = "div",class_ = "wdesc").string)
temp = str(info.find(name = "div",class_ = "temp").string)
direct = str(info.find(name = "div",class_ = "direct").string)
wind = str(info.find(name = "div",class_ = "wind").string)
thisDay["date"] = date
thisDay["week"] = week
thisDay["wdesc"] = wdesc
thisDay["temp"] = temp
thisDay["direct"] = direct
thisDay["wind"] = wind
dirt[thisDay["date"]] = thisDay
return dirt
except:
return {}
首先先聲明dirt為一個字典,然后把html用beautifulSoup庫對其進行解析,解析后的soup對象可以調用它的find方法和find_all方法開始尋找我們需要的信息所對應的標簽。至於哪個信息對應哪個標簽,可以在瀏覽器中用ctrl + F的快捷鍵調出搜索框。獲取到我們需要的信息后,我們可以把它進行加工保存在每天的thisDay字典里,然后再把7天的thisDay字典加入dirt字典里,最后返回dirt字典。具體的加工方法就是用split方法切片、提取。當然也可以選擇正則表達式,需要額外再引用re庫。
然后是解析圖片:
def parserHTMLPicture(imag,imagLink):
try:
soup = BeautifulSoup(imag,"html.parser")
# next_url = soup.find(name = 'link',rel = 'next')['href']
# next_page = getHTMLText(next_url)
imagAddress = soup.find(name='div',class_ = 'photolst clearfix').find_all(name = 'img')
for image in imagAddress:
imagLink.append(image['src'])
return imagLink
except:
return []
解析圖片我們只需要把圖片的地址獲取到imagLink列表中即可。然后我們遍歷這個列表,並且下載這些圖片:
def downloadPicture(url,name):
root = 'C:\\Users\\10990\\Pictures\\'#這里填保存的路徑
path = root + str(name) + '.jpg'
try:
if not os.path.exists(root):
os.mkdir(root)
if not os.path.exists(path):
r = requests.get(url)
with open(path,'wb') as f:
f.write(r.content)
f.close()
print("文件保存成功")
else:
print("文件已存在")
except:
print("爬取失敗")
在下載前我們要注意判斷路徑是否存在,若不存在要建立一個,在開始爬之前要留意是否已經爬取過,若已經存在則跳過。命名我是以數字順序命名的,在后續調用中也更方便。
然后我們需要新建一個txt文件,用來保存本次發送的照片名字,注意該文件應該和代碼的py文件保存在同一路徑下。
回到main()方法
with open('pictureName.txt','r') as f:
name = eval(f.read())
f.close()
with open('pictureName.txt','w') as f:
newName = str(name + 1)
f.write(newName)
f.close()
msgRoot = makeMessage(whetherInfo,name)
sendMsg(msgRoot)
然后我們讀取當前的圖片名,賦給name,再把name名加一后重新保存下來,這樣每天發給女票的就是一張新的圖片了。然后要把我們的天氣信息和我們每天想說的話以及圖片打包成一個email對象發送出去就行啦。
def makeMessage(dirt,image):
#編輯消息
print(dirt)
message = dirt["place"]+' 今天 '
items = {'wdesc','temp','direct','wind'}
for item in items:
message += dirt["\n 今天\n "][item].strip('\n ')+" "
for temp in message.split(" "):
if temp.find("℃") != -1:
if eval(temp.split("℃")[0]) > 25:
message += "今天很熱,盡量別出門啦"
elif eval(temp.split("℃")[0]) < 12:
message += "今天很冷,注意保暖"
if message.find("雨") != -1:
message += " 出門的話記得帶傘"
print(message)
#生成郵件對象
msgRoot = MIMEMultipart('related')
msgRoot['From'] = Header("我是發信人","utf-8")
msgRoot['To'] = Header('我是收信人','utf-8')
subject = '赴戍登程口占示家人'
msgRoot['Subject'] = Header(subject,'utf-8')
msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)
mail_msg = '''
<p> 力微任重久神疲,再竭衰庸定不支。
苟利國家生死以,豈因禍福避趨之?
謫居正是君恩厚,養拙剛於戍卒宜。
戲與山妻談故事,試吟斷送老頭皮。
</p>
<p>'''+message+'''</p>
<p><img src = "cid:image1"></p>
'''
msgAlternative.attach(MIMEText(mail_msg,'html','utf-8'))
catalog = 'C:\\Users\\10990\\Pictures\\' + str(image) + ".jpg"
#指定圖片為當前目錄
with open(catalog,'rb') as fp:
msgImage = MIMEImage(fp.read())
fp.close()
#定義圖片在ID,在HTML文本中引用
msgImage.add_header('Content-ID','<image1>')
msgRoot.attach(msgImage)
return msgRoot
def sendMsg(message):
mail_host = "smtp.qq.com"#要使用的smtp服務器
mail_user = "*******"#用戶名和密碼
mail_pass = "********"
sender = '********'#發送者
receivers = ['*******']#收信者,注意這里是一個列表,就是說可以群發,當然勸君莫浪~~
try:
smtpObj = smtplib.SMTP()
smtpObj.connect(mail_host)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login(mail_user,mail_pass)
smtpObj.sendmail(sender,receivers,message.as_string())
print("郵件發送成功")
smtpObj.quit()
except smtplib.SMTPException:
print("Error:無法發送郵件")
往后都是可以從網上找到的代碼,當然了各位也可以更進一步,從網上爬取各種騷話,用同樣的方式解析並加入email對象中,為了不吃狗糧小編決定交給各位自己發掘(其實就是懶)需要注意,圖片我們只爬取了一頁的圖片,各位還可以自行添加代碼,完成自動換頁之后的爬取,因為圖片有限,當我們的txt文件數大於18,即自動發送18天后,需要另外爬取第二頁的圖片。
另外,推薦把程序掛到服務器上面,做個定時發送。每天准點發送。這樣妹子就可以天天收到你的雲關懷啦。
記得讓女票把你加入白名單,否則你發過去的郵件都會被投進垃圾箱的。
完整代碼
欲獲取代碼,請關注我們的微信公眾號【程序猿聲】,在后台回復:pylove。即可下載。

