banner
andrewji8

Being towards death

Heed not to the tree-rustling and leaf-lashing rain, Why not stroll along, whistle and sing under its rein. Lighter and better suited than horses are straw sandals and a bamboo staff, Who's afraid? A palm-leaf plaited cape provides enough to misty weather in life sustain. A thorny spring breeze sobers up the spirit, I feel a slight chill, The setting sun over the mountain offers greetings still. Looking back over the bleak passage survived, The return in time Shall not be affected by windswept rain or shine.
telegram
twitter
github

Python自動化-頭條、抖音、微博熱搜採集分析

這是一個自媒體常用案例,今天我們通過分析這個案例來獲得有關 python 的學習和使用

效果
通過運行 py 腳本輸出本地得到 xlsx 數據表格文件

1、 自動化分類;整體匹配率:84%~96% 區間左右。

2、 詞頻統計;三者共存的熱搜,說明為持久公共熱度,信息密度較高。

3、 文本情感平均值、每條標題的情感數值;主:人為置頂熱搜的文本情緒強烈程度。

4、 詞性分析;標記可能存有引導與被植入意識成分用詞,只要定語、狀語疊得多,總能是宣傳正態形勢。

640 (1)

代碼#

import os
from datetime import datetime
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook
from snownlp import SnowNLP
import jieba
from collections import Counter
import jieba.posseg as pseg
import json
import urllib.request

# 確定保存文本格式用的。
def get_formatted_time():
    """
    獲取格式化後的當前時間
    :return: 格式化後的當前時間字符串
    """
    now = datetime.now()
    return now.strftime('%Y-%m-%d')

# 解析新聞函數
def get_news_from_url(url: str):
    """
    從指定的 URL 抓取熱搜新聞
    :param url: 網頁 URL
    :return: 熱搜新聞列表
    """
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                      '(KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
    r = requests.get(url, headers=headers)
    r.encoding = 'utf-8'
    soup = BeautifulSoup(r.text, 'html.parser')
    toutiao_resoubang = soup.find_all('div', class_='single-entry tindent')

    resoubang_list = []
    for item in toutiao_resoubang:
        spans = item.find_all('span')
        for span in spans:
            resoubang_list.append(span.string)
    return resoubang_list

# 刪除空行
def delete_empty_rows(sheet_name: str, wb: Workbook):
    """
    刪除指定工作表中的空行
    :param sheet_name: 工作表名稱
    :param wb: Excel 工作簿對象
    :param None 關鍵字
    https://notes-by-yangjinjie.readthedocs.io/zh_CN/latest/python/05-modules/openpyxl.html?highlight=openpyxl
    """
    ws = wb[sheet_name]
    # 迭代行所用的內置函數 ws.iter_rows()
    for row in ws.iter_rows():
        if all(cell.value is None for cell in row):
            ws.delete_rows(row[0].row)

# 計數平均指數、情感得分
def calculate_average_index_and_sentiment_score(sheet_name: str, wb: Workbook):
    """
    計算指定工作表中熱搜新聞的平均指數和情感得分
    :param sheet_name: 工作表名稱
    :param wb: Excel 工作簿對象
    :return: 平均指數、情感得分元組
    """
    ws = wb[sheet_name]
    total_index = 0
    count = 0
    sentiment_score_list = []
    for row in ws.iter_rows(min_row=2, min_col=1, max_col=3):
        news_str = ''
        for cell in row:
            if cell.value is not None:
                news_str += str(cell.value)
        # 功能挺多,見:https://github.com/isnowfy/snownlp
        s = SnowNLP(news_str)
        sentiment_score = s.sentiments
        sentiment_score_list.append(sentiment_score)
        # row[2] 是指每一行中的第三個單元格,也就是第三列。
        total_index += row[2].value
        count += 1
        ws.cell(row=row[0].row, column=4, value=sentiment_score)
    # 每張表的平均指數與情感得分
    return (total_index / count, sum(sentiment_score_list) / len(sentiment_score_list))

# 統計詞頻
def calculate_word_count(sheet_names: list, wb: Workbook):
    """
    計算工作表中出現最多的20個單詞,將結果寫入新的工作表中
    :param sheet_names: 工作表名稱
    :param wb: Excel 工作簿對象
    :param stopwords_file: 停用詞文件路徑
    停用詞是指在自然語言中使用頻率很高,
    但通常不具有實際含義或對文本分析任務沒有太大幫助的單詞,如“的”,“了”等。
    """
    
    # 停用詞文件
    stopwords_file = 'https://ghproxy.com/https://raw.githubusercontent.com/goto456/stopwords/master/cn_stopwords.txt'
    # 請求停用詞庫
    response = requests.get(stopwords_file)
    stopwords = response.content.decode('utf-8').split('\n')

    # 加載停用詞庫
    for word in stopwords:
        jieba.del_word(word.strip())

    # 遍歷所有工作表,統計詞頻,由於語料庫詞彙功能欠佳,只能粗略統計
    word_count = Counter()
    for sheet_name in sheet_names:
        ws = wb[sheet_name]
        for row in ws.iter_rows(min_row=2, min_col=1, max_col=3):
            news_str = ''
            for cell in row:
                if cell.value is not None:
                    news_str += str(cell.value)
            words = jieba.lcut(news_str)

            # 只要是數值類型的忽略。
            # words = [word for word in words if not(word.isdigit() or (word.replace('w', '').replace('.', '').isdigit()))]
            new_words = []
            for word in words:
                 # 忽略長度為 0 或 1 的字符串
                if len(word) <= 1:
                    continue
                # 去除數值噪聲
                if not(word.isdigit() or (word.replace('w', '').replace('.', '').isdigit())):
                    new_words.append(word)
            words = new_words
            # 更新詞庫集
            word_count.update(words)

    # 去掉停用詞
    for word in list(word_count):
        if word in stopwords:
            del word_count[word]

    # 取出出現最多的30個詞
    top_words = word_count.most_common(30)
    # 創建一個新的工作表
    ws = wb.create_sheet(title='詞頻統計')
    # 添加行
    ws.append(['排名', '詞語', '詞頻'])
    # 從1開始計數,而非0開始排名
    for i, (word, freq) in enumerate(top_words,1):
        ws.append([i, word, freq])


# 2023.5.9 新增分類功能
def write_category_to_sheet(sheet_name: str, wb: Workbook):
    """
    將新聞事件的關鍵詞分類信息寫入到 Excel 工作表中的第五列中
    :param sheet_name: 工作表名稱
    :param wb: Excel 工作簿對象
    :jieba分詞:https://github.com/fxsjy/jieba
    """

    # 調用在線分類字典 json
    # 從URL獲取JSON數據
    response = urllib.request.urlopen('https://ghproxy.com/https://raw.githubusercontent.com/hoochanlon/scripts/main/AQUICK/category_news.json')
    json_data = response.read().decode('utf-8')

    # 解析JSON數據
    category_keywords = json.loads(json_data)

    # 從當前sheet開始
    ws = wb[sheet_name]
    for row in ws.iter_rows(min_row=2, min_col=1, max_col=4):
        title_str = ''
        for cell in row:
            if cell.value is not None:
                title_str += str(cell.value)

        # 將標題字符串分詞並轉換為列表數組
        words = pseg.cut(title_str)
        category = ''
        for word, flag in words:
            # 內置的字符串方法,用於檢查前綴指定開頭
            # if flag.startswith('n'):
            # key keywords 關鍵字,.items() 檢索鍵值對
                for key, keywords in category_keywords.items():
                    if word in keywords:
                        category = key
                        break
                if category:
                    break
        if not category:
           # category = '其他'
            category = '綜合'
        ws.cell(row=row[0].row, column=5, value=category)


# 將已解析網頁排版的數據,按規則寫入到xlsx,行列對稱,條理分明。
def write_news_to_sheet(news_list: list, sheet_name: str, wb: Workbook):
    """
    將新聞列表寫入到 Excel 工作表中
    :param news_list: 新聞列表
    :param sheet_name: 工作表名稱
    :param wb: Excel 工作簿對象
    :cell.value.isnumeric() 表示當前字符串是否能表示為一個數字
    :isinstance(cell.value, str) 表示當前值是否字符串
    """
    ws = wb.create_sheet(title=sheet_name)

    row = []
    for i, item in enumerate(news_list, start=1):
        if i >= 156: # 抽取50組數據(如果索引大於 156 是關於微博的其他介紹文章)
            continue  
        if i % 3 == 1: #  # 索引從0開始,即2%3,往後是新組數據。
            item = item.replace("、", "")
        row.append(item)
        if i % 3 == 0: # 取模被整除,3列一組,被整除說明已到3列,換行。
            ws.append(row)
            row = []
    
    # 從第二行開始迭代每一行數據
    for row in ws.iter_rows(min_row=2, min_col=1):
        for cell in row:
            if cell.column == 1 or cell.column == 3:
                # 實例判斷,如果是返回 True,否則返回 False。
                if isinstance(cell.value, str) and not cell.value.isnumeric():
                    # 去除字符串中的 '[置頂]' 字符,185為2、3、4排名的平均值(實時)
                    cell.value = cell.value.replace('[置頂]', '185w') 
                if isinstance(cell.value, str) and cell.value.isnumeric():
                    cell.value = int(cell.value)
                elif isinstance(cell.value, str):
                    cell.value = float(cell.value.replace('w', ''))

    ws.cell(row=1, column=3, value='指數(萬)')
    ws.cell(row=1, column=4, value='情感得分')
    ws.cell(row=1, column=5, value='分類')
    

def main():

    urls = ['http://resou.today/art/11.html', 'http://resou.today/art/22.html','http://resou.today/art/6.html']
    sheet_names = ['今日頭條熱榜', '抖音時事熱榜', '微博熱搜']

    wb = Workbook()

    wb.remove(wb['Sheet'])
    for url, sheet_name in zip(urls, sheet_names):
        news_list = get_news_from_url(url)
        # 寫入網頁解析的數據到xlsx
        write_news_to_sheet(news_list, sheet_name, wb)
        # 刪除操作留下的空行
        delete_empty_rows(sheet_name, wb)
        # 分類
        write_category_to_sheet(sheet_name, wb)

        # 統計平均指數、各表平均情感值
        average_index, sentiment_score = calculate_average_index_and_sentiment_score(sheet_name, wb)
        print(f'{sheet_name} 平均指數:{average_index:.2f} 情感得分: {sentiment_score:.2f}')
    
    # 詞頻統計
    calculate_word_count(sheet_names, wb)

    # 進行跨平台處理保存路徑
    save_path_xlsx_file = os.path.join(os.path.join(os.path.expanduser("~"), "Desktop"), 
                                       "resoubang_{}.xlsx".format(get_formatted_time()))
    # 刪除空表,並保存為指定文件
    # wb.remove(wb['Sheet']);wb.save(save_path_xlsx_file)
    wb.save(save_path_xlsx_file)

# 如果當前模塊是被其他模塊導入的,則該條件語句下面的代碼將不會被執行。
if __name__ == '__main__':
    main()

分析#

透過代碼我們首先看到代碼第一部分導入了一些常用的 Python 庫和模塊

import os:這是 Python 的標準庫之一,用於與操作系統進行交互,例如創建文件夾、刪除文件等操作。

from datetime import datetime:從 datetime 模塊中導入 datetime 方法,用於處理日期和時間的功能。

import requests:這是一個非常常用的庫,用於發送 HTTP 請求,例如獲取網頁內容。

from bs4 import BeautifulSoup:從 BeautifulSoup 模塊中導入 BeautifulSoup 類,用於解析和提取 HTML 或 XML 文檔中的數據。

from openpyxl import Workbook:從 openpyxl 模塊中導入 Workbook 類,用於操作 Excel 文件。

from snownlp import SnowNLP:從 snownlp 模塊中導入 SnowNLP 類,用於中文文本情感分析。

import jieba:這是一個非常常用的中文分詞庫,用於將中文文本分割成一個個單詞。

from collections import Counter:從 collections 模塊中導入 Counter 類,用於對一個可迭代對象進行計數。

import jieba.posseg:導入 jieba 庫中的 posseg 模塊,用於中文詞性標註。

import json:這是 Python 的標準庫之一,用於處理 JSON 數據。

import urllib.request:這是 Python 的標準庫之一,用於發送 HTTP 請求和處理 URL。

整體部分解釋#

它使用了上面多個第三方庫來實現不同的功能。

接下來,代碼定義了一個函數 get_formatted_time (),用於獲取格式化後的當前時間。

然後,代碼定義了一個函數 get_news_from_url (url: str),用於從指定的 URL 抓取熱搜新聞。

接著,代碼定義了一個函數 delete_empty_rows (sheet_name: str, wb: Workbook),用於刪除指定工作表中的空行。

然後,代碼定義了一個函數 calculate_average_index_and_sentiment_score (sheet_name: str, wb: Workbook),用於計算指定工作表中熱搜新聞的平均指數和情感得分。

接下來,代碼定義了一個函數 calculate_word_count (sheet_names: list, wb: Workbook),用於統計工作表中出現最多的 20 個單詞。

然後,代碼定義了一個函數 write_category_to_sheet (sheet_name: str, wb: Workbook),用於將新聞事件的關鍵詞分類信息寫入到 Excel 工作表中。

接著,代碼定義了一個函數 write_news_to_sheet (news_list: list, sheet_name: str, wb: Workbook),用於將新聞列表寫入到 Excel 工作表中。

最後,代碼定義了一個函數 main (),用於執行主要的程序邏輯。它首先定義了要抓取的 URL 和工作表名稱的列表,然後創建了一個 Excel 工作簿對象。接著,它使用 get_news_from_url () 函數抓取熱搜新聞,並使用 write_news_to_sheet () 函數將新聞列表寫入到 Excel 工作表中。然後,它使用 delete_empty_rows () 函數刪除空行,並使用 write_category_to_sheet () 函數將關鍵詞分類信息寫入到 Excel 工作表中。接著,它使用 calculate_average_index_and_sentiment_score () 函數計算平均指數和情感得分,並打印結果。最後,它使用 calculate_word_count () 函數統計詞頻,並將工作簿保存為 xlsx 文件。

最後,代碼使用 if name == 'main': 條件語句判斷當前模塊是否被直接執行,如果是,則調用 main () 函數執行主程序邏輯。

使用#

安裝 python
下載 Python:首先,您需要下載並安裝 Python 解釋器。您可以在 Python 官方網站(https://www.python.org)上找到不同版本的 Python。選擇適合您操作系統的版本並下載安裝程序。

安裝 Python:運行下載的安裝程序,並按照安裝向導的指示進行安裝。確保選擇將 Python 添加到系統路徑中的選項。

如果要運行 Python 文件:打開命令提示符(Windows)或終端(Mac/Linux),導航到存儲了 Python 腳本的目錄。使用 cd 命令來切換目錄,例如:cd C:\Users\YourUsername\Documents 然後,可以運行以下命令來執行 Python 腳本:python example.py 這樣,您就可以安裝和運行 Python 文件了。如果一切順利,您應該能夠在命令提示符或終端中看到輸出結果。

注:python3.x 版本運行 python3 example.py 才會執行文件

設置 python 的全局環境變量#

打開終端應用程序。您可以在 “應用程序” 文件夾中找到它,或者使用 Spotlight 搜索並輸入 “終端”。

在終端中,輸入以下命令來編輯您的 bash 配置文件(如果您使用的是 Zsh,請將命令中的.bash_profile 替換為.zshrc):

nano ~/.bash_profile

終端將打開一個文本編輯器,顯示您的bash配置文件的內容(如果您沒有創建過配置文件,則會是空白的)。

在文件的末尾添加以下行來設置 Python 的全局環境變量:

export PATH="/usr/local/bin:$PATH"

這將將/usr/local/bin目錄添加到您的PATH環境變量中,該目錄通常是Python安裝的位置。

按下 Control + X 來退出文本編輯器,然後按下 Y 來保存更改,最後按下 Enter 鍵確認保存的文件名。

在終端中,輸入以下命令來使更改生效:

source ~/.bash_profile

這將重新加載您的bash配置文件,使更改立即生效。

現在,您已經成功設置了 Python 的全局環境變量。您可以在終端中運行 python 命令來驗證是否正確設置。

正確驗證伺服器證書
如果在使用 python 時 urllib 庫發送 HTTPS 請求出現了證書驗證失敗的問題

為了解決這個問題,您可以嘗試以下步驟:

打開終端應用程序。

輸入以下命令並按 Enter 鍵:

/applications/python\ {your_python_version}/install\ Certificates.command

請將{your_python_version}替換為您當前使用的Python版本號。例如,如果您使用的是Python 3.10,則命令應為:

/applications/python\ 3.10/install\ Certificates.command

執行上述命令後,將會自動下載並安裝缺失的根證書。

這個命令會運行 Python 安裝目錄中的 Install Certificates.command 腳本,用於安裝缺失的根證書。執行此命令後,您的 Python 環境應該能夠正確驗證伺服器證書,而不會再出現證書驗證失敗的錯誤。

PIP 安裝文件依賴庫
輸入以下命令來檢查是否已經安裝了 pip:

pip --version

如果已經安裝了pip,您將看到pip的版本信息。如果未安裝,您將看到一條錯誤消息。

如果未安裝 pip,您可以使用以下方法之一來安裝它:

在命令行中運行以下命令來安裝 pip:

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

sudo python get-pip.py

在瀏覽器中打開 https://bootstrap.pypa.io/get-pip.py。

將頁面上的內容保存為名為 get-pip.py 的 Python 腳本文件。

在命令行中導航到保存了 get-pip.py 文件的目錄。

運行以下命令來安裝 pip:

python get-pip.py
對於 Windows 用戶:

對於 Mac 和 Linux 用戶:

安裝完成後,您可以再次運行以下命令來驗證 pip 是否已成功安裝:

如果顯示了 pip 的版本信息,那麼 pip 已經成功安裝了。

pip --version

現在可以在終端使用以下命令安裝所需的依賴庫:pip install requests beautifulsoup4 openpyxl snownlp jieba要使用import os和from datetime import datetime這兩個庫,它們是Python的內置庫,無需安裝。至於import jieba.posseg as pseg和import urllib.request,它們是Python標準庫的一部分,也不需要單獨安裝。如果使用pip安裝時出現權限問題,可以添加–user參數來將庫安裝在用戶目錄下:pip install –user requests beautifulsoup4 openpyxl snownlp jieba

最後,在滿足 python 必要環境、文件所需依賴庫的情況下使用終端命令或 python 解釋器直接運行文件即可。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。