一、步骤思路:

  • 打开热搜首页​​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)

看下效果,这就是对应生成的指定文件格式的文件:

爬虫之获取各大网站热搜_python

再看看日志的打印:

/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

 到此,便完成了今天相关热搜的获取。

以上的写法有很多扩展,因为获取的路径url一样,以及定位的xpath元素有很多大共性,只是id不同,所以我做了很大程度的小分装,包括对生成结果文件的格式的指定也可以通过配置来指定,关于文件名的配置,我觉得没用多大必要,就写成了手动传入。