回覆“書籍”即可獲贈Python從入門到進階共10本電子書
最近微博的瓜一個接一個,本文就將介紹如何用 Python 自動抓取微博熱搜,並定時發送到QQ郵箱。主要分爲三部分:
-
爬取微博熱搜 -
整理數據與發送郵箱 -
定時執行
一、抓取熱搜數據
進入微博熱搜榜https://s.weibo.com/top/summary
後,整體頁面如下:
可以看到,我們需要的熱搜榜單信息在頁面的正中央(總共50條熱搜),這裏我們需要爬取的信息有熱搜標題、話題搜索量、以及話題指數。按F12
進入網頁源代碼頁面,點擊element
內容如下:
選中鼠標選項,點擊你要爬取的信息,就可以看到對應的html源碼。這裏我們爬取的分爲三個部分:標題、數量、指數、網址四個信息,而我們可以從網頁源代碼發現如下規律:
信息 | 源代碼規律 |
---|---|
標題 | <a href="……" target="_blank">標題</a> |
數量 | <span>數量</span> |
指數 | <td class="td-03">指數</td> |
指數1 | <i class="……">(.*?)</i> |
連接 | <a href="連接" target="_blank">標題</a> |
注意:這裏之所以有指數和指數1源代碼是因爲前者獲取到的數據是有雜音的,所以需要再次用到指數1獲得最終的信息。
之後我們運用requests
包爬取網頁源代碼並通過re
模塊對爬取內容進行正則提取,因爲每天僅執行一次,也就不用考慮請求頭什麼的,Python代碼如下:
import requests
import re
url = 'https://s.weibo.com/top/summary?cate=realtimehot' #微博網址
ret = requests.get(url)
test = ret.text
u_href = '<a href="(.*?)" target="_blank">.*?</a>'
u_title = '<a href=".*?" target="_blank">(.*?)</a>'
u_amount = '<span>(.*?)</span>'
u_category = '<td class="td-03">(.*?)</td>'
u_href = '<a href="(.*?)" target="_blank">.*?</a>'
title = re.findall(u_title,test)
amount = re.findall(u_amount,test)
category = re.findall(u_category,test)
href = re.findall(u_href,test)
二、數據清洗
上面獲取到的title
、amount
、category
、href
四個指標是未經處理的話題、話題搜索量、話題指數、話題連接。接下來我們對其進行處理,先上代碼
import pandas as pd
title = title[:-2]
title = title[1:]
href = href[:-2]
href = href[1:]
for j in range(len(href)):
href[j] = 'https://s.weibo.com/' + href[j]
while '' in amount:
amount.remove('')
for i in range(len(category)):
if category[i] != '':
category[i] = re.findall('<i class=".*?">(.*?)</i>',category[i])[0]
if category[i] == '':
category[i] = '空'
category = category[1:]
while '薦' in category:
category.remove('薦')
df = pd.DataFrame()
df['關鍵詞'] = title
df['amount'] = amount
df['category'] = category
df['href'] = href
df = df.sort_values('amount')
df2 = df[df['category']=='爆']
df3 = df[df['category']=='沸']
df4 = df[df['category'] == '熱']
df5 = df[df['category'] == '新']
df6 = df[df['category'] == '空']
df = pd.concat([df2,df3,df4,df5,df6],ignore_index = True)
df.to_csv('微博熱搜.csv',encoding = 'gbk')#輸出爲csv文本格式
下面對title進行處理,第一節爬取到的title是這樣的,
總共只有50條熱搜,怎麼多出來3條?可以看到最後的兩條是不需要的,所以用列表提取的方法提取前50行。還有一個元素多出來?就是我們的第一個元素,即是title[0],title[0]是沒有序號與熱搜搜索量的,如圖:
“天問一號成功着陸”這一話題有指數無搜索量,是屬於缺失數據,這裏我們刪除它,同樣用到列表提取元素方法。
對href
連接的處理與title
的處理相同。
接着對搜索量做處理,採用了刪除空格的語句。原因是熱搜榜中會出現推薦的話題,而推薦的話題是沒有搜索量的,故我們刪除它。
最後輪到指數處理,先看未處理前的指數,
上面顯而易見我們要提取的指數信息就在每個元素裏面,同樣利用re
模塊正則提取,提取出來後做三件事:
-
去除第一個元素(原因已在title處理上講解) -
空字符串部分以中文空子代替 -
去除推薦的話題
上面三步的代碼已附上。代碼裏最後的步驟就是運用pandas
模塊對數據進行整理得到美觀的數據框形式。效果如下:
三、發郵箱與設置定時
用Python可以模擬許多大廠的郵箱發送,本文選擇常用的騰訊QQ郵箱。在此之前需要做一個準備(獲取SMTP授權碼):
登錄QQ郵箱並單擊設置按鈕,然後進入賬戶這個頁面
進入之後向下拖動來到POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務
這欄,這裏單擊POP3/SMTP服務
右側的開啓,單擊後會有一個驗證密保的過程,按照提示即可。最終會彈出一個框,裏面包含SMTP授權碼,這裏可以找個地方記錄起來,Python代碼就可以用到。
先上發送QQ郵箱的代碼模板:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
number = '你的QQ郵箱號碼'
smtp = '郵箱對應的STMP授權碼'
to = '需要發送到的QQ郵箱號碼' # 可以是非QQ的郵箱
mer = MIMEMultipart()
# 設置郵件正文內容
head = '''
<p>微博熱搜榜信息</p>
<p>最熱門詞條爲</p>
<p><a href="{}">{}</a></p>
<p>排名前五的熱搜</p>
<p><a href="{}">{}</a></p>
<p><a href="{}">{}</a></p>
<p><a href="{}">{}</a></p>
<p><a href="{}">{}</a></p>
<p><a href="{}">{}</a></p>
'''.format(df.iloc[0,:]['href'],df.iloc[0,:]['關鍵詞'],
df.iloc[1,:]['href'],df.iloc[1,:]['關鍵詞'],
df.iloc[2,:]['href'],df.iloc[2,:]['關鍵詞'],
df.iloc[3,:]['href'],df.iloc[3,:]['關鍵詞'],
df.iloc[4,:]['href'],df.iloc[4,:]['關鍵詞'],
df.iloc[5,:]['href'],df.iloc[5,:]['關鍵詞'])
mer.attach(MIMEText(head, 'html', 'utf-8'))
fujian = MIMEText(open('微博熱搜.csv', 'rb').read(), 'base64', 'utf-8')
fujian["Content-Type"] = 'application/octet-stream' #附件內容
fujian.add_header('Content-Disposition', 'file', filename=('utf-8', '', '微博熱搜.csv'))
mer.attach(fujian)
mer['Subject'] = '每日微博熱搜榜單' #郵件主題
mer['From'] = number #發送人
mer['To'] = to #接收人
# 5.發送郵件
s = smtplib.SMTP_SSL('smtp.qq.com', 465)
s.login(number, smtp)
s.send_message(mer) # 發送郵件
s.quit()
print('成功發送')
代碼框架基本如此,你需要更改的地方有如下,其餘的內容可以不改:
-
郵件主題 -
發送人 -
接收人 -
SMTP授權碼 -
附件內容
運行成功後,輸出框會有“成功發送”打印,如果你的微信綁定了你的發送QQ郵箱,那麼你就可以點擊其中的附件,也就是csv文件。
按照我們設置的格式,把最熱門的詞條和排名前五的詞條放入head正文內容中,效果如下:
(這裏存在延時,所以熱搜榜和上面不一)
最後就是設置定時執行這個代碼也即是發送微博熱搜榜信息,利用Schedule
庫可以實現。
schedule
模塊設置定時的模板只需改2個地方,一個是schedule.every().day.at("18:00").do(email)
中的時間,一個是def函數裏面運行的內容。While True的作用就是讓程序不停止。
我們定每晚6點進行自動發送,代碼如下:
import schedule
import time
def email():
number = '你的QQ郵箱號碼'
smtp = '郵箱對應的STMP授權碼'
to = '需要發送到的QQ郵箱號碼' # 可以是非QQ的郵箱
mer = MIMEMultipart()
# 設置郵件正文內容
head = '''
<p>微博熱搜榜信息</p>
<p>最熱門詞條爲</p>
<p><a href="{}">{}</a></p>
<p>排名前五的熱搜</p>
<p><a href="{}">{}</a></p>
<p><a href="{}">{}</a></p>
<p><a href="{}">{}</a></p>
<p><a href="{}">{}</a></p>
<p><a href="{}">{}</a></p>
'''.format(df.iloc[0,:]['href'],df.iloc[0,:]['關鍵詞'],
df.iloc[1,:]['href'],df.iloc[1,:]['關鍵詞'],
df.iloc[2,:]['href'],df.iloc[2,:]['關鍵詞'],
df.iloc[3,:]['href'],df.iloc[3,:]['關鍵詞'],
df.iloc[4,:]['href'],df.iloc[4,:]['關鍵詞'],
df.iloc[5,:]['href'],df.iloc[5,:]['關鍵詞'])
mer.attach(MIMEText(head, 'html', 'utf-8'))
fujian = MIMEText(open('微博熱搜.csv', 'rb').read(), 'base64', 'utf-8')
fujian["Content-Type"] = 'application/octet-stream' #附件內容
fujian.add_header('Content-Disposition', 'file', filename=('utf-8', '', '微博熱搜.csv'))
mer.attach(fujian)
mer['Subject'] = '每日微博熱搜榜單' #郵件主題
mer['From'] = number #發送人
mer['To'] = to #接收人
# 5.發送郵件
s = smtplib.SMTP_SSL('smtp.qq.com', 465)
s.login(number, smtp)
s.send_message(mer) # 發送郵件
s.quit()
print('成功發送')
schedule.every().day.at("18:00").do(email)
while True:
schedule.run_pending()
time.sleep(5)
這樣,我們就完成了利用 Python 自動爬取微博熱搜,並在每天指定時間自動發送整理後的結果至郵箱。當然你也可以自已更改邏輯,例如 當出現指定關鍵詞、指定tag時發送郵箱,感興趣的讀者可以來一波三連~
------------------- End -------------------
往期精彩文章推薦:
歡迎大家點贊,留言,轉發,轉載,感謝大家的相伴與支持
想加入Python學習羣請在後臺回覆【入羣】
萬水千山總是情,點個【在看】行不行
/今日留言主題/
隨便說一兩句吧~~
本文分享自微信公衆號 - Python爬蟲與數據挖掘(crawler_python)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。