一、前言
這篇文章是基于對上篇文章爬蟲之擷取各大網站熱搜的進階優化修改并添加了語音播報的功能,其中的封裝如果有更好的建議,希望更多的讀者能過提提,下面就要開始我的創作了。
二、針對上篇文章,總體做了以下修改
1、配置檔案的優化,調用盡量避免傳入太多無用的參數,是以我這邊隻保留了url、headers、hot_path三個配置:
hot_top_http:
url: https://tophub.today/
headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36' }
hot_xpath:
# 綜合
- //div[ @id='node-1' ]/div # 微網誌
- //div[ @id='node-6' ]/div # 知乎
- //div[ @id='node-5' ]/div # 微信
- //div[ @id='node-2' ]/div # 百度
# 科技
- //div[ @id='node-11' ]/div # 36氪
- //div[ @id='node-137' ]/div # 少數派
- //div[ @id='node-32' ]/div # 虎嗅網
- //div[ @id='node-119' ]/div # IT之家
# 娛樂
- //div[ @id='node-19' ]/div # 哔哩哔哩
- //div[ @id='node-221' ]/div # 抖音
- //div[ @id='node-72' ]/div # 煎蛋
- //div[ @id='node-26' ]/div # 豆瓣小組
# 社群
- //div[ @id='node-68' ]/div # 吾愛破解
- //div[ @id='node-3' ]/div # 百度貼吧
- //div[ @id='node-46' ]/div # 天涯
- //div[ @id='node-42' ]/div # 虎撲社群
# 購物
- //div[ @id='node-5666' ]/div # 淘寶
- //div[ @id='node-167' ]/div # 什麼值得買
- //div[ @id='node-26696' ]/div # 今日熱賣
- //div[ @id='node-4416' ]/div # 拼多多
# 财經
- //div[ @id='node-215' ]/div # 雪球
- //div[ @id='node-2413' ]/div # 第一财經
- //div[ @id='node-2497' ]/div # 财新網
- //div[ @id='node-252' ]/div # 新浪财經新聞
# 大學
- //div[ @id='node-36' ]/div # 水木社群
- //div[ @id='node-27469' ]/div # 北大未名
- //div[ @id='node-41' ]/div # 武大珞珈山水
- //div[ @id='node-37' ]/div # 北師蛋蛋
# 日報
- //div[ @id='node-125' ]/div # 知乎日報
- //div[ @id='node-289' ]/div # 開眼視訊
- //div[ @id='node-257' ]/div # 百度知道日報
- //div[ @id='node-9402' ]/div # 哔哩哔哩
# 地方門戶
- //div[ @id='node-2594' ]/div # 高樓迷
- //div[ @id='node-2568' ]/div # 蘇州姑蘇網
- //div[ @id='node-102' ]/div # 寬帶山
- //div[ @id='node-25' ]/div # 光谷社群
# 影視
- //div[ @id='node-85' ]/div # 豆瓣電影
- //div[ @id='node-73' ]/div # 貓眼
- //div[ @id='node-4439' ]/div # 知乎-影視
- //div[ @id='node-5205' ]/div # 豆瓣電影
# 閱讀
- //div[ @id='node-5819' ]/div # 微信讀書
- //div[ @id='node-88' ]/div # 當當
- //div[ @id='node-5832' ]/div # 起點中文網
- //div[ @id='node-5846' ]/div # 縱橫中文網
# 遊戲
- //div[ @id='node-60' ]/div # TapTap
- //div[ @id='node-3524' ]/div # 3DM遊戲網
- //div[ @id='node-295' ]/div # 機核網
- //div[ @id='node-203' ]/div # 遊研社
# 體育
- //div[ @id='node-251' ]/div # 新浪體育新聞
- //div[ @id='node-4437' ]/div # 知乎-體育
- //div[ @id='node-316' ]/div # 虎撲社群
- //div[ @id='node-26571' ]/div # 新浪熱點榜
# 産品
- //div[ @id='node-213' ]/div # 人人都是産品經理
- //div[ @id='node-293' ]/div # 鳥哥筆記
- //div[ @id='node-300' ]/div # 産品100
- //div[ @id='node-133' ]/div # Product Hunt
# 開發
- //div[ @id='node-54' ]/div # GitHub
- //div[ @id='node-267' ]/div # CSDN論壇
- //div[ @id='node-100' ]/div # 掘金
- //div[ @id='node-132' ]/div # 開發者頭條
# 應用
- //div[ @id='node-62' ]/div # App Store
- //div[ @id='node-2429' ]/div # 愛範兒
- //div[ @id='node-392' ]/div # 最美應用
- //div[ @id='node-3510' ]/div # AppSo
# 汽車
- //div[ @id='node-2454' ]/div # 汽車之家
- //div[ @id='node-66' ]/div # 老司機
- //div[ @id='node-2464' ]/div # 易車網
- //div[ @id='node-2460' ]/div # 太平洋汽車網
# 安全
- //div[ @id='node-89' ]/div # 看雪論壇
- //div[ @id='node-327' ]/div # 安全客
- //div[ @id='node-326' ]/div # FreeBuf
- //div[ @id='node-328' ]/div # 安全脈搏
2、新增自命名方法:
# -*- coding: utf-8 -*-
"""
@author: lucas
@Function: 檔案命名,分為預設檔案名和自定義檔案名
@file: fileNaming.py
@time: 2021/10/3 5:47 下午
"""
import os
from utils.config import Config
def fileNaming(path1):
print("請輸入檔案名,如不輸入,預設檔案名export: ")
DEFAULT_FILE_NAME = Config().get('general_parameters').get('default_file_name')
exportname = input()
if exportname == '':
exportname = DEFAULT_FILE_NAME
if os.path.exists('%s\%s.xlsx' % (path1, exportname)):
os.remove('%s\%s.xlsx' % (path1, exportname))
print('導出檔案路徑: %s/%s.xlsx' % (path1, exportname))
return exportname
3、寫入資料方法優化:
3.1 将檔案格式作為數組闖入
3.2 合并重複路徑代碼
# -*- coding: utf-8 -*-
"""
@author: lucas
@Function: 定義寫入檔案類型
@file: writeHotToFile.py
@time: 2021/9/29 2:28 下午
"""
import os
import openpyxl
import pandas as pd
from utils.config import DATA_PATH, Config
from utils.fileNaming import fileNaming
FORMAT = ['.html', '.csv', '.json', '.xlsx']
def writeHotToFile(data, n):
file = pd.DataFrame(data, columns=['排名', '今日熱搜', '熱度(機關為萬)'])
print(file)
encoding = Config().get('general_parameters').get('charset')
exportname = fileNaming(DATA_PATH)
if n >= len(FORMAT):
print("Error: 數組大小超限")
else:
base_path = DATA_PATH + '/' + exportname + FORMAT[n]
if n == 0:
return file.to_html(base_path, encoding=encoding[1])
elif n == 1:
return file.to_csv(base_path)
elif n == 2:
return file.to_json(base_path, force_ascii=False)
elif n == 3:
return file.to_excel(base_path)
else:
return "抱歉!沒有找到符合的檔案格式,請重新輸入!"
4、新增播報方法
# -*- coding: utf-8 -*-
"""
@author: lucas
@Function: 語音播報功能
@file: voiceBroadcast.py
@time: 2021/10/2 4:00 下午
"""
import pyttsx3
def voiceBroadcast(speckingRate, content):
"""
speckingRate: 語速
content: 需要播報的内容
"""
engine = pyttsx3.init()
rate = engine.getProperty('rate')
engine.setProperty('rate', speckingRate)
engine.say(content)
engine.runAndWait()
engine.stop()
# -*- coding: utf-8 -*-
"""
@author: lucas
@Function: 擷取熱搜的方法
@file: getHot.py
@time: 2021/9/29 12:16 下午
"""
from lxml import etree
from utils.client import HTTPClient
from utils.voiceBroadcast import voiceBroadcast
from utils.writeHotToFile import writeHotToFile
def getHot(methods, url, headers, xpath, n):
"""
methods: 請求方法
url: 請求路徑
headers: 請求頭
xpath: 定位的清單路徑
n: 對應着檔案格式,0-html,1-csv,2-json,3-xlsx......
range_num: 排名數量
"""
html = HTTPClient(url, methods, headers).send()
html = html.content.decode('utf-8')
html = etree.HTML(html)
div = html.xpath(xpath)
for a in div:
titles = a.xpath(".//span[@class='t']/text()")
numbers = a.xpath(".//span[@class='e']/text()")
b = []
for i in range(len(titles)):
list = [f"排行榜第:{i + 1} 今日熱搜:{titles[i]},熱度為:{numbers[i][:-1]}"]
voiceBroadcast(200, '為您播報今天微網誌熱搜:' + list[0])
b.append([i + 1, titles[i], numbers[i][:-1]])
writeHotToFile(b, n)
# -*- coding: utf-8 -*-
from utils.client import METHODS
from utils.getHot import getHot
from utils.config import Config
if __name__ == '__main__':
http = Config().get('hot_top_http')
headers = http.get('headers')
url = http.get('url')
hot_xpath = http.get('hot_xpath')
# 微網誌熱搜排行
getHot(METHODS[0], url, headers, hot_xpath[0], 0)