# Python3 爬虫实战 — 虎扑论坛步行街

TRHX

2019-10-12

Python3 学习笔记 / 爬虫实战

字数统计:

1,453字

阅读时长≈

7分

> 爬取时间：2019-10-12
> 爬取难度：★★☆☆☆☆
> 请求链接：https://bbs.hupu.com/bxj
> 爬取目标：爬取虎扑论坛步行街的帖子，包含主题，作者，发布时间等，数据保存到 MongoDB 数据库
> 涉及知识：请求库 requests、解析库 Beautiful Soup、数据库 MongoDB 的操作
> 完整代码：https://github.com/TRHX/Python3-Spider-Practice/tree/master/hupu
> 其他爬虫实战代码合集（持续更新）：https://github.com/TRHX/Python3-Spider-Practice
> 爬虫实战专栏（持续更新）：https://itrhx.blog.csdn.net/article/category/9351278

# 【1x00】循环爬取网页模块

观察虎扑论坛步行街分区，请求地址为：https://bbs.hupu.com/bxj

第一页：https://bbs.hupu.com/bxj

第二页：https://bbs.hupu.com/bxj-2

第三页：https://bbs.hupu.com/bxj-3

不难发现，每增加一页，只需要添加 `-页数` 参数即可，最后一页是第 50 页，因此可以利用 for 循环依次爬取，定义一个 `get_pages()` 函数，返回初始化 Beautiful Soup 的对象 page_soup，方便后面的解析函数调用

虽然一共有 50 页，但是当用户访问第 10 页以后的页面的时候，会要求登录虎扑，不然就没法查看，而且登录时会出现智能验证，所以程序只爬取前 10 页的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    def get_pages(page_url):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
        }
        response = requests.get(url=page_url, headers=headers)
        page_soup = BeautifulSoup(response.text, 'lxml')
        return page_soup

    if __name__ == '__main__':
        for i in range(1, 11):
            url = 'https://bbs.hupu.com/bxj-' + str(i)
            soup = get_pages(url)

# 【2x00】解析模块

使用 Beautiful Soup 对网页各个信息进行提取，最后将这些信息放进一个列表里，然后调用列表的 `.append()` 方法，再将每条帖子的列表依次加到另一个新列表里，最终返回的是类似于如下形式的列表：

    1

    [['帖子1', '作者1'], ['帖子2', '作者2'], ['帖子3', '作者3']]

这样做的目的是：方便 MongoDB 依次储存每一条帖子的信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39

    def parse_pages(page_soup):
        data_list = []
        all_list = page_soup.find('ul', class_='for-list')
        post_list = all_list.find_all('li')
        # print(result_list)
        for post in post_list:
            # 帖子名称
            post_title = post.find('a', class_='truetit').text
            # print(post_title)
            # 帖子链接
            post_url = 'https://bbs.hupu.com' + post.find('a', class_='truetit')['href']
            # print(post_url)
            # 作者
            author = post.select('.author > a')[0].text
            # print(author)
            # 作者主页
            author_url = post.select('.author > a')[0]['href']
            # print(author_url)
            # 发布日期
            post_date = post.select('.author > a')[1].text
            # print(post_date)
            reply_view = post.find('span', class_='ansour').text
            # 回复数
            post_reply = reply_view.split('/')[0].strip()
            # print(post_reply)
            # 浏览量
            post_view = reply_view.split('/')[1].strip()
            # print(post_view)
            # 最后回复时间
            last_data = post.select('.endreply > a')[0].text
            # print(last_data)
            # 最后回复用户
            last_user = post.select('.endreply > span')[0].text
            # print(last_user)

            data_list.append([post_title, post_url, author, author_url, post_date, post_reply, post_view, last_data, last_user])

        # print(data_list)
        return data_list

# 【3x00】MongoDB 数据储存模块

首先使用 `MongoClient()` 方法，向其传入地址参数 host 和 端口参数 port，指定数据库为 `hupu`，集合为 `bxj`

将解析函数返回的列表传入到储存函数，依次循环该列表，对每一条帖子的信息进行提取并储存

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    def mongodb(data_list):
        client = MongoClient('localhost', 27017)
        db = client.hupu
        collection = db.bxj
        for data in data_list:
            bxj = {
                '帖子名称': data[0],
                '帖子链接': data[1],
                '作者': data[2],
                '作者主页': data[3],
                '发布日期': str(data[4]),
                '回复数': data[5],
                '浏览量': data[6],
                '最后回复时间': str(data[7]),
                '最后回复用户': data[8]
            }
            collection.insert_one(bxj)

# 【4x00】完整代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95

    # =============================================
    # --*-- coding: utf-8 --*--
    # @Time    : 2019-10-12
    # @Author  : TRHX
    # @Blog    : www.itrhx.com
    # @CSDN    : https://blog.csdn.net/qq_36759224
    # @FileName: hupu.py
    # @Software: PyCharm
    # =============================================

    import requests
    import time
    import random
    from pymongo import MongoClient
    from bs4 import BeautifulSoup

    def get_pages(page_url):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
        }
        response = requests.get(url=page_url, headers=headers)
        page_soup = BeautifulSoup(response.text, 'lxml')
        return page_soup

    def parse_pages(page_soup):
        data_list = []
        all_list = page_soup.find('ul', class_='for-list')
        post_list = all_list.find_all('li')
        # print(result_list)
        for post in post_list:
            # 帖子名称
            post_title = post.find('a', class_='truetit').text
            # print(post_title)
            # 帖子链接
            post_url = 'https://bbs.hupu.com' + post.find('a', class_='truetit')['href']
            # print(post_url)
            # 作者
            author = post.select('.author > a')[0].text
            # print(author)
            # 作者主页
            author_url = post.select('.author > a')[0]['href']
            # print(author_url)
            # 发布日期
            post_date = post.select('.author > a')[1].text
            # print(post_date)
            reply_view = post.find('span', class_='ansour').text
            # 回复数
            post_reply = reply_view.split('/')[0].strip()
            # print(post_reply)
            # 浏览量
            post_view = reply_view.split('/')[1].strip()
            # print(post_view)
            # 最后回复时间
            last_data = post.select('.endreply > a')[0].text
            # print(last_data)
            # 最后回复用户
            last_user = post.select('.endreply > span')[0].text
            # print(last_user)

            data_list.append([post_title, post_url, author, author_url, post_date, post_reply, post_view, last_data, last_user])

        # print(data_list)
        return data_list

    def mongodb(data_list):
        client = MongoClient('localhost', 27017)
        db = client.hupu
        collection = db.bxj
        for data in data_list:
            bxj = {
                '帖子名称': data[0],
                '帖子链接': data[1],
                '作者': data[2],
                '作者主页': data[3],
                '发布日期': str(data[4]),
                '回复数': data[5],
                '浏览量': data[6],
                '最后回复时间': str(data[7]),
                '最后回复用户': data[8]
            }
            collection.insert_one(bxj)

    if __name__ == '__main__':
        for i in range(1, 11):
            url = 'https://bbs.hupu.com/bxj-' + str(i)
            soup = get_pages(url)
            result_list = parse_pages(soup)
            mongodb(result_list)
            print('第', i, '页数据爬取完毕！')
            time.sleep(random.randint(3, 10))
        print('前10页所有数据爬取完毕！')

# 【5x00】数据截图

一共爬取到 1180 条数据：

<fancybox>
</fancybox>

# 【6x00】程序不足的地方

程序只能爬取前 10 页的数据，因为虎扑论坛要求从第 11 页开始，必须登录账号才能查看，并且登录时会有智能验证，可以使用自动化测试工具 Selenium 模拟登录账号后再进行爬取。

您的喜欢是作者写作最大的动力！❤️

- PayPal
- AliPay
- WeChatPay
- QQPay

Donate

最后更新于 2019年10月21日

爬虫

虎扑论坛

###### 上一页

#### Python3 爬虫实战 — 模拟登陆哔哩哔哩【滑动验证码对抗】

###### 爬虫 哔哩哔哩

###### 下一页

#### Python3 爬虫实战 — 安居客武汉二手房

###### 爬虫 安居客

#### 评论

## ๑۩ﺴ TRHX ﺴ۩๑

本文目录
欢迎光临

Hexo QQ 交流群 Telegram 交流群

CSDN 内容合伙人

文章分类

- BLOG
  (4)
- CDN
  (1)
- Hexo
  (9)
- Java
  (1)
- Linux
  (2)
- Markdown
  (2)
- Python 数据分析
  (27)
- Matplotlib
  (11)
- NumPy
  (6)
- Pandas
  (10)
- Python3 学习笔记
  (41)
- 基础学习
  (9)
- 学习经验
  (4)
- 爬虫学习
  (18)
- 爬虫实战
  (10)
- VPS
  (1)
- WEB前端
  (2)
- 图床
  (1)

热门标签
12306 3D图 58同城 Ajax BLOG Beautiful Soup CDN Coding Pages DataFrame Deepin Elicpse GitHub Pages Github Github Pages GroupBy HTTPS Hexo ICP备案 IO操作 Index JDBC JS 预加载 LaTeX Markdown Material X Matplotlib MongoDB MySQL NumPy PEP8 Pandas PicGo Pygame Python Redis SEO SQL Server 2012 SSR Selenium Series Ubuntu User-Agent VMware VPS XPath if语句 input()函数 instant.page jsDelivr lxml matplotibrc pyspider requests spfk urllib while循环 主题个性化 代理 位运算 公安备案 函数 函数应用 分割 切片 列表 判断函数 前程无忧 变量 合并数据集 哔哩哔哩 图例 图床 图形验证码 垃圾 备份 子图 字典 字符串函数 安居客 层级索引 年终总结 广播 异常 技巧 拼接 排序 排序函数 操作列表 散点图 数学函数 数据分裂 数据可视化 数据合并 数据替换 数据类型 数据读写 数据重塑 数组 文件 文件储存 无界面浏览器 时间序列 映射 条件函数 条形图 极区图 极坐标图 柱状图 模块 正则表达式 滑动验证码 点触验证码 爬虫 猫眼电影 瓜子二手车 画布 直方图 矩阵 等值线图 等高线图 算术函数 算术运算 类 索引 线性代数 线性图 统计函数 统计描述 统计计算 继承 编辑器 缺失值 网格 肺炎疫情 虎扑论坛 补丁 豆瓣电影 迭代 雷达图 饼状图
最近在听