天天看點

爬蟲之擷取各大網站熱搜

一、步驟思路:

  • 打開熱搜首頁​​https://tophub.today/​​
  • 右鍵點選檢查,分析靜态網頁
  • 将爬取到的内容儲存為指定檔案格式

二、開始項目

1、編寫定義寫入檔案類型為後面的擷取熱搜方法做鋪墊,在utils中建立 writeHotToFile.py檔案:

# -*- coding: utf-8 -*-

"""
@author: lucas
@Function: 定義寫入檔案類型
@file: writeHotToFile.py
@time: 2021/9/29 2:28 下午
"""
import pandas as pd

from utils.config import DATA_PATH


def writeHotToFile(data, file_name, file_format):
    """
    data: 需要寫入的資料
    file_name: 檔案名
    file_format: 檔案格式
    """
    file = pd.DataFrame(data, columns=['排名', '今日熱搜', '熱度(機關為萬)'])
    print(file)
    print(DATA_PATH)
    if file_format == '.html':
        file.to_html(DATA_PATH + '/' + file_name + '.html', encoding='utf_8_sig')
    elif file_format == '.csv':
        file.to_csv(DATA_PATH + '/' + file_name + '.csv')
    elif file_format == '.json':
        file.to_json(DATA_PATH + '/' + file_name + '.json', force_ascii=False)
    elif file_format == '.xlsx':
        file.to_excel(DATA_PATH + '/' + file_name + '.xlsx')
    else:
        print("沒有找到合适的檔案格式!")      

這邊的DATA_PATH來源于我之前寫的config.py檔案:

# -*- coding: utf-8 -*-
"""
@author: lucas
@Function:讀取配置。這裡配置檔案用的yaml,也可用其他如XML,INI等,需在file_reader中添加相應的Reader進行處理。
@file: config.py
@time: 2021/9/6 1:50 下午
"""

import os

# 通過目前檔案的絕對路徑,其父級目錄一定是架構的base目錄,然後确定各層的絕對路徑。如果你的結構不同,可自行修改。
# 之前直接拼接的路徑,修改了一下,用現在下面這種方法,可以支援linux和windows等不同的平台,也建議大家多用os.path.split()和os.path.join(),不要直接+'\\xxx\\ss'這樣
from utils.file_reader import YamlReader

BASE_PATH = os.path.split(os.path.dirname(os.path.abspath(__file__)))[0]
print(BASE_PATH)
CONFIG_FILE = os.path.join(BASE_PATH, 'config', 'config.yml')
DATA_PATH = os.path.join(BASE_PATH, 'data')
DRIVER_PATH = os.path.join(BASE_PATH, 'drivers')
LOG_PATH = os.path.join(BASE_PATH, 'log')
REPORT_PATH = os.path.join(BASE_PATH, 'report')


class Config:
    def __init__(self, config=CONFIG_FILE):
        self.config = YamlReader(config).data

    def get(self, element, index=0):
        """
        yaml是可以通過'---'分節的。用YamlReader讀取傳回的是一個list,第一項是預設的節,如果有多個節,可以傳入index來擷取。
        這樣我們其實可以把架構相關的配置放在預設節,其他的關于項目的配置放在其他節中。可以在架構中實作多個項目的測試。
        """
        return self.config[index].get(element)


if __name__ == '__main__':
    c = Config()
    print(BASE_PATH)
    print(CONFIG_FILE)
    print(REPORT_PATH)      

2、編寫擷取熱搜的方法,在utils中建立getHot.py檔案:

# -*- coding: utf-8 -*-

"""
@author: lucas
@Function: 擷取熱搜的方法
@file: getHot.py
@time: 2021/9/29 12:16 下午
"""
import requests
from lxml import etree

from utils.writeHotToFile import writeHotToFile


# 擷取請求url
def get_url(methods, url, headers):
    try:
        response = requests.request(method=methods, url=url, headers=headers)
        if response.status_code == 200:
            return response
    except requests.ConnectionError as e:
        print(e.args)


def getHot(methods, url, headers, xpath, file_name, file_format, range_num):
    """
    methods: 請求方法
    url: 請求路徑
    headers: 請求頭
    xpath: 定位的清單路徑
    file_name: 檔案名
    file_format: 檔案格式
    range_num: 排名數量
    """
    html = get_url(methods, url, headers)
    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(range_num):
        b.append([i + 1, titles[i], numbers[i][:-1]])
    writeHotToFile(b, file_name, file_format)      

3、對讀取的傳參檔案做參數化配置:

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' }
  methods: GET
  weibo_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 # 安全脈搏
  file_format:
    - .html
    - .csv
    - .json
    - .xlsx
  range: 10      

這其中運用了好多知識點,預設都是字元串格式的值,有對對象的定義--需要加{},也有對數組類型的寫法,例如- xxx 就是對數組的定義,寫法很多,可以自己上網找教程

4、測試代碼如下:

# -*- coding: utf-8 -*-
from utils.getHot import getHot
from utils.config import Config

if __name__ == '__main__':
    http = Config().get('hot_top_http')
    headers = http.get('headers')
    methods = http.get('methods')
    url = http.get('url')
    weibo_xpath = http.get('weibo_xpath')
    file_format = http.get('file_format')
    range_num = http.get('range')
    file_name_weibo = '微網誌熱搜榜熱度資料'
    file_name_asknown = '知乎熱搜榜熱度資料'
    # 微網誌熱搜排行
    getHot(methods, url, headers, weibo_xpath[0], file_name_weibo, file_format[0], range_num)
    # 知乎熱搜排行
    getHot(methods, url, headers, weibo_xpath[1], file_name_asknown, file_format[1], range_num)      

看下效果,這就是對應生成的指定檔案格式的檔案:

爬蟲之擷取各大網站熱搜
/Users/leiyuxing/PycharmProjects/TestFramework
    排名                  今日熱搜  熱度(機關為萬)
0    1            他不是藥神隻是個父親     328.1
1    2     15歲少年開保時捷載4未成年上高速     111.9
2    3        山姆會員店菌菇湯料現白色蟲子     101.3
3    4        孫怡說婚姻讓我的人生特别豐滿  綜藝 97161
4    5          國慶三倍薪水加班你願意嗎      89.6
5    6          重慶姐弟墜亡案生母再發聲      79.0
6    7     家長給4歲孩子買成人感冒藥老闆怒拒      74.6
7    8          黃貫中回應被叫Paul媽  綜藝 71479
8    9           鱿魚遊戲運動服有多眼熟  劇集 51110
9   10             百香果應該叫百搭果      49.1
10  11         前經紀人舉報韓磊涉稅務問題      49.1
11  12  大學教授說娶到大才女李清照是倒了八輩子黴      48.9
12  13           該不該把舊手機給媽媽用      47.9
13  14              嗦完螺蛳粉坐電梯      42.8
14  15          中國空軍喊話某國雲端相見      42.4
15  16          還以為室友在床頭挂了豬肉      41.4
16  17              牙醫到底有多吃香      41.0
17  18    女子第一次上瑜伽私教課被老師壓斷大腿      39.1
18  19         岸田文雄當選日本自民黨總裁      36.0
19  20           全紅婵祝大家國慶節快樂      34.2
20  21           劉亦菲好像有采訪NB症      33.6
21  22            趙麗穎幸福到萬家片花  劇集 33216
22  23           黑龍江疫情正處于關鍵期      32.6
23  24            銀行對我們的信任程度      32.5
24  25              吳宣儀演了個齊葩  劇集 30351
/Users/leiyuxing/PycharmProjects/TestFramework/data
    排名                                               今日熱搜 熱度(機關為萬)
0    1              如何看待上海小區加裝電梯,底層業主有些不滿,認為其他樓層房價會漲的更厲害?  2010 萬熱
1    2                 一戰裡的聖誕節停戰,英法德士兵互相休息娛樂。這種情況為何二戰沒有呢?   877 萬熱
2    3                      如何看待廣東宏遠隊籃球運動員胡明軒成為阿迪達斯籃球代言人?   722 萬熱
3    4       湖南地窖囚禁性侵 16 歲未成年少女 24 天案罪犯被執行死刑,還有哪些值得關注的資訊?   607 萬熱
4    5               韓劇《鱿魚遊戲》第一季第 9 集結尾,男主成奇勳為什麼做出了那樣的選擇?   495 萬熱
5    6  重慶一女子醫院就診時突然摔倒緻十級傷殘,經調查是一男孩在醫院走廊弄灑飲料所緻,究竟哪方該為此...   487 萬熱
6    7                岸田文雄當選日本自民黨新任總裁,将出任首相,日本政壇風向可能如何轉變?   478 萬熱
7    8        安徽稱「出生人口連續 4 年減少,人口形勢極為嚴峻」,可能的原因是什麼?應該如何解決?   432 萬熱
8    9                       你怎麼看「孩子在幼稚園被打了,教育他該打回去」這種做法?   386 萬熱
9   10                                 有什麼食物第一口很好吃,越吃越難吃?   375 萬熱
10  11       媒體揭「病媛」帶貨套路,聲稱自己患病實則為産品帶貨,如何看待此類行為?這反映出什麼問題?   350 萬熱
11  12          如何看待雲米冰箱回應「強推廣告可以關閉,晚點出教程」?遇到強推廣告問題該如何解決?   325 萬熱
12  13     如何看待醫科男生入學 5 天因「色盲」被退學,聯考指定機構複檢為色弱,學校稱依入學體檢結果?   312 萬熱
13  14                     火币網宣布停止國内新使用者注冊,年底前清退存量使用者意味着什麼?   297 萬熱
14  15         如何看待河南醉漢闖進國小打校長,校長反擊打掉其 3 顆牙,兩人均被拘?具體情況如何?   278 萬熱
15  16         如何看待媒體評「限電是一盤大棋」:亂帶節奏中産生了不小的「低級紅」「進階黑」的效果?   269 萬熱
16  17                                         永生是否是一種酷刑?   259 萬熱
17  18      「上海金沙江路 5 死 7 傷交通事故案」宣判,被告人陳某偉被判死刑,如何從法律角度解讀?   257 萬熱
18  19                                    如何看待微信推出「關懷模式」?   233 萬熱
19  20             為什麼釣魚魚竿這麼講究,直接拿根硬棍子,咬鈎了往上提不就完了,誰能解釋一下?   223 萬熱
20  21          廣州、深圳暫停國慶燈光秀,景觀照明縮短亮燈時間,路燈照明适當調整,将帶來哪些影響?   223 萬熱
21  22         如何看待新東方單方面取消合同内容,每個月隻發 1000 多的工資逼員工自己走的操作?   222 萬熱
22  23                                  長期不讀書的話,會降低表達能力嗎?   222 萬熱
23  24                                為什麼長期健身,身體強壯了,人卻虛了?   216 萬熱
24  25   中科院專家表示已開始核聚變發電站工程設計,不存在核洩漏,有望 10 年内示範發電,這意味着什麼?   215 萬熱
/Users/leiyuxing/PycharmProjects/TestFramework/data

Process finished with exit code 0