从网页抓取数据(Python中解析网页的一个重要的应用,使用Python爬虫 )

优采云 发布时间: 2022-03-25 02:23

  从网页抓取数据(Python中解析网页的一个重要的应用,使用Python爬虫

)

  爬虫是 Python 的一个重要应用。使用Python爬虫,我们可以很方便的从网上抓取我们想要的数据

  本文将以爬取并存储B站视频热搜榜数据为例,详细介绍Python爬虫的基本流程。

  如果你还处于爬取的入门阶段或者不知道爬取的具体工作流程,那么你应该仔细阅读这篇文章!

  第 1 步:尝试请求

  先进入b站首页,点击排行榜,复制链接

  https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3

  现在启动 Jupyter notebook 并运行以下代码

  import requests

url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'

res = requests.get('url')

print(res.status_code)

#200

  在上面的代码中,我们完成了以下三件事

  可以看到返回值为200,表示服务器正常响应,表示我们可以继续

  第 2 步:解析页面

  上一步中,我们通过requests向网站请求数据后,成功获得了一个收录服务器资源的Response对象。现在我们可以使用 .text 查看它的内容

  

  可以看到返回的是一个字符串,里面收录了我们需要的热榜视频数据,但是直接从字符串中提取内容复杂且效率低下,所以我们需要对其进行解析,将字符串转换成网页结构数据,即使查找 HTML 标记及其属性和内容变得容易。

  Python解析网页的方式有很多种,可以使用正则表达式,也可以使用BeautifulSoup、pyquery或lxml,本文将基于BeautifulSoup进行讲解

  Beautiful Soup 是一个第三方库,可以从 HTML 或 XML 文件中提取数据

  安装也很简单,使用 pip install bs4 安装即可

  让我们用一个简单的例子来说明它是如何工作的

  from bs4 import BeautifulSoup

page = requests.get(url)

soup = BeautifulSoup(page.content, 'html.parser')

title = soup.title.text 

print(title)

# 热门视频排行榜 - 哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

  在上面的代码中,我们通过bs4中的BeautifulSoup类将上一步得到的html格式字符串转换成BeautifulSoup对象。请注意,使用时需要指定解析器。这里我们使用 html.parser

  然后您可以获得结构元素之一及其属性。例如,使用 soup.title.text 获取页面标题。您还可以使用soup.body、soup.p 等来获取任何需要的元素。

  第三步:提取内容

  上面两步中,我们使用requests向网页请求数据,使用bs4解析页面。现在我们来到最关键的一步:如何从解析后的页面中提取出需要的内容。

  在 Beautiful Soup 中,我们可以使用 find/find_all 来定位元素,但我更喜欢使用 CSS 选择器 .select 因为可以像使用 CSS 选择元素一样沿着 DOM 树向下移动

  现在我们用代码来说明如何从解析后的页面中提取B站热榜的数据。首先,我们需要找到存储数据的标签,在列表页按F12按照下面的说明找到

  

  可以看到每个视频信息都包裹在class="rank-item"的li标签下,那么代码可以这样写

  all_products = []

products = soup.select('li.rank-item')

for product in products:

    rank = product.select('div.num')[0].text

    name = product.select('div.info > a')[0].text.strip()

    play = product.select('span.data-box')[0].text

    comment = product.select('span.data-box')[1].text

    up = product.select('span.data-box')[2].text

    url = product.select('div.info > a')[0].attrs['href']

    all_products.append({

        "视频排名":rank,

        "视频名": name,

        "播放量": play,

        "弹幕量": comment,

        "up主": up,

        "视频链接": url

    })

  在上面的代码中,我们首先使用了soup.select('li.rank-item'),然后返回一个收录每个视频信息的列表,然后遍历每个视频信息,仍然使用CSS选择器来提取我们想要的字段信息,并存储在开头以字典形式定义的空列表中

  可以注意到我使用了多种选择方法来提取元素,这也是选择方法的灵活性。有兴趣的读者可以自行进一步研究。

  第 4 步:存储数据

  通过前三步,我们成功使用requests+bs4从网站中提取出需要的数据,最后只需要将数据写入Excel并保存即可。

  如果对pandas不熟悉,可以使用csv模块写,需要注意设置encoding='utf-8-sig',否则会出现中文乱码问题

  import csv

keys = all_products[0].keys()

with open('B站视频热榜TOP100.csv', 'w', newline='', encoding='utf-8-sig') as output_file:

    dict_writer = csv.DictWriter(output_file, keys)

    dict_writer.writeheader()

    dict_writer.writerows(all_products)

  如果您熟悉 pandas,您可以通过一行代码轻松地将字典转换为 DataFrame

  import pandas as pd

keys = all_products[0].keys()

pd.DataFrame(all_products,columns=keys).to_csv('B站视频热榜TOP100.csv', encoding='utf-8-sig')

  

  概括

  至此,我们已经成功使用Python将b站热门视频列表的数据存储在本地。大多数基于请求的爬虫基本上都遵循以上四个步骤。

  不过,虽然看起来很简单,但在实景中的每一步都不是那么容易的。从请求数据来看,目标网站有各种形式的反爬取、加密,以及后期分析、提取甚至存储数据。需要进一步探索和学习。

  本文选择B站视频热榜,正是因为够简单。希望通过这个案例大家可以了解爬虫的基本流程,最后附上完整代码

  import requests

from bs4 import BeautifulSoup

import csv

import pandas as pd

url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'

page = requests.get(url)

soup = BeautifulSoup(page.content, 'html.parser')

all_products = []

products = soup.select('li.rank-item')

for product in products:

    rank = product.select('div.num')[0].text

    name = product.select('div.info > a')[0].text.strip()

    play = product.select('span.data-box')[0].text

    comment = product.select('span.data-box')[1].text

    up = product.select('span.data-box')[2].text

    url = product.select('div.info > a')[0].attrs['href']

    all_products.append({

        "视频排名":rank,

        "视频名": name,

        "播放量": play,

        "弹幕量": comment,

        "up主": up,

        "视频链接": url

    })

keys = all_products[0].keys()

with open('B站视频热榜TOP100.csv', 'w', newline='', encoding='utf-8-sig') as output_file:

    dict_writer = csv.DictWriter(output_file, keys)

    dict_writer.writeheader()

    dict_writer.writerows(all_products)

### 使用pandas写入数据

pd.DataFrame(all_products,columns=keys).to_csv('B站视频热榜TOP100.csv', encoding='utf-8-sig')

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线