Python3 网络爬虫 02 <爬取文字·元尊小说>
@ 我的老师:Jack Cui

PS:我是通过 看 Jack Cui 老师的文章 学习的爬虫,也为我之后的 爬虫打开了大门。


通常我们学习爬虫,都感觉是一个 很难的事儿。但实际不然。爬虫 无非就是要 爬取 四样有用的 东西!

文字 图片 音乐 视频

那么这一节,我们就要 去网络上下载一篇小说。即 文字 的爬取。


2.1.1 爬虫基本步骤

① URL
URL:https://www.yingsx.com/

② 发送请求

我们需要先 明确如何发起 HTTP 请求,获取到 数据。而暂时我们 能够接触到的 请求类型就是 GET (即通过显露的 URL 和 相关参数 来进行 目的资源和目的数据的 直接获取)

解析数据 <今天的重点>

当我们访问了 目的资源 后,我们就可以拿到源代码,在这个源代码里。我们就能 提取 出 我们想要的数据。

④ 保存数据

将我们想要的数据保存下来,保存到文件 中。是我们 刚接触爬虫 最常用的手段。这样我们 在用到某些数据的时候,通过 文件的读取 即可。


解析数据 有很多种方式:

字符串的解析 (通过自身的 逻辑经验,代码能力,可以配合 一些原生态的 字符串方法 来实现 目的数据的提取)【难度: ⭐⭐⭐⭐

正则表达式 (正则表达式 大家应该都知道,它通常用来 匹配相应的字符串。) 若不知道的同学,可以 点击这篇文章学习一下:< 程序员必备知识 01 正则表达式 >

解析数据的模块 (虽然模块千千多!但这里建议大家使用 xpath、BeautifulSoup 这两者)+ re 正则模块,就可以很好的 起到 解析数据的效果。【难度: ⭐⭐


2.1.2 Beautiful Soup

① 安装 Beautiful Soup

pip install beautifulsoup4

Beautiful Soup 官方中文文档
Python3 网络爬虫 02 <爬取文字·元尊小说>

PS:这里建议大家 跟着 我的教程走,慢慢找感觉,你会发现 学习编程,没有什么比 直接敲代码实践 来得轻松,来得快了。

② 安装 lxml (以 lxml 方式来进行解析)

pip install lxml

Python3 网络爬虫 02 <爬取文字·元尊小说>


Python3 网络爬虫 02 <爬取文字·元尊小说>

我们先来看下 这个 URL:https://www.yingsx.com/0_100/

Python3 网络爬虫 02 <爬取文字·元尊小说>
右键 检查,你会在 上面的 工具栏里,看到 一个 小鼠标,点击这个小鼠标,再对你感兴趣的 数据进行 点击。你会发现 它自动的 将 该数据在源代码中的位置 跳转显现了出来。

Python3 网络爬虫 02 <爬取文字·元尊小说>

而这张图,我们又可以知道。我们 每一章节 都有一个 URL。

这些 URL 都在 描述列表or自定义列表<dd> URL <\dd> 标签中。

那么 我们 就先 教 大家 利用 Beatiful Soup 模块 来进行 这些 URL 的爬取。


2.2.2 爬取 每一章 的 URL

① 先来看下 我们最基本的 源代码是否能爬取成功。

import requests

# get 方式访问 URL
req = requests.request(method="GET",url = "https://www.yingsx.com/0_100/")
# 编码调节为 UTF-8
req.encoding = 'utf-8'

print(req.text)

Python3 网络爬虫 02 <爬取文字·元尊小说>

② 利用 BeautifulSoup 进行 lxml 的解析。

--> 并通过 bs.find() 先找到 list 这个 div 大框,因为在它的内部 才有 那些个 dd

--> 再根据 获取到 list div 元素,find_all('dt')[1] 找到 第二个 dt 标签,因为我们可以清楚的看到,真正的所有 URL 都在 第二个标签的后面

--> 然后 我们 让 dt = find_all('dt')[1]dt.find_all_next('dd') 就可以获取到 之后的所有 dd 标签了。

--> 最后 我们 再根据 每个 dd 来 find('a') 里面的 每个 a 标签。
Python3 网络爬虫 02 <爬取文字·元尊小说>

import requests
from bs4 import BeautifulSoup

# get 方式访问 URL
URL = "https://www.yingsx.com/0_100/"
req = requests.request(method="GET",url=URL)
# 编码调节为 UTF-8
req.encoding = 'utf-8'
#print(html)
html = req.text
# 以lxml 方式进行解析
bs = BeautifulSoup(html,'lxml')

# 我们要获取的标签是 div,而这个 div 的 标识 是 id = 'list'
list = bs.find("div",)
# 通过 这个 div 获取到 内部的 第二个 dt
dt = list.find_all('dt')[1]

# a 标签 列表
aList = []
# url 列表
urlList = []
# name 文章名 列表
nameList = []

# dt.find_all_next('dd') 找到 第二个 dt 标签后 所有的 dd 返回一个 列表
for dd in dt.find_all_next('dd'):
    # 获取每个 dd 标签 内部的 a 标签
    aList.append(dd.find('a'))
    # 获取每个 a 标签 的 href 属性值,即 每一章 的 url
    urlList.append('https://www.yingsx.com'+ dd.find('a').get('href'))
    # 获取每个 a 标签 的 内容,即 每一章 的 标题名
    nameList.append(dd.find('a').text)

for url in urlList:
    print(url)

Python3 网络爬虫 02 <爬取文字·元尊小说>

BeautifulSoup(待分析的字符串源码,分析的格式or方式) 提供一个待分析的字符串,和 分析的格式或方式,我们就会 得到一个 bs对象。该对象 的数据结构 是一棵树,当然我们也不需进行细节的刨析。我们只要知道 我们拿到这个对象,就相当于 拿到了 你提供的源代码的解析器。

bs.find(元素标签的名称,定位标识) 我们可以通过 某些定位标识,比如 它的 独有属性 id ,或者 class 等 来确认 它是哪一个 元素。

bs.find_all(元素标签的名称,定位的标识) 它是 在 定位标识 ok 的情况下,当然一般 这个方法 不会写 定位标识。它会把 所有符合的标签,都获取出来,并且 存储到一个 列表里。

dt.find_all_next(元素标签的名称,定位的标识) 它是 在 当前这个元素的基础上,往下 再去探索 所有的 符合标识的 标签。

元素标签.text 能够直接获取到 标签内 写的 大白话文字。比如我们这次获取 到的 就是 每一章的名字!

元素标签.get('属性名') 通过属性名 获取到该元素 对应的属性值。


2.2.2 爬取 每一章 的 小说内容

接下来,我们就要 对 每一个文章 的 页面内容和源代码 进行 分析。

Python3 网络爬虫 02 <爬取文字·元尊小说>

我们会发现呢,每一章的内容 其实都 在 <div ></div> 标签里。

所以我们同理,依靠 上面的 步骤和教程。可以很轻松的 得到 这个内容。


但是问题来了

① 我们获取到的内容,有 &nbsp;&nbsp;&nbsp;&nbsp; 这个特殊标识符,在 html 里面,代表 空格。但是 我们 如果 是字符串的话。空格 就是 空格呀 ~ ~ 哪还有这个 &nbsp 所以我们要把 它 替换为 空格

content = content.text.strip().split('\xa0' * 4,' ')

其实上面这行代码是一个简化版。看下面的代码就知道了!

content = content.text.split('\xa0' * 4)
for i,x in enumerate(content):
	content[i] = x .strip()

PS已有网友 提醒,其实没必要 进行替换,读取出来 后,就是 四个空格。哈哈 ~ 我当时 写的很急促。这个代码…… 大意了!没闪 ~

Python3 网络爬虫 02 <爬取文字·元尊小说>

② 我们肯定是要 写 到文件里的,要不然 我们爬虫的意义何在。

用最 python 自带的,也是最简单的 文件操作即可解决该问题 ……


我们先 根据我们的 思路 写一章 看看吧!!!

import requests
from bs4 import BeautifulSoup
import os

# get 方式访问 URL
URL = "https://www.yingsx.com/0_100/"
req = requests.request(method="GET",url=URL)
# 编码调节为 UTF-8
req.encoding = 'utf-8'
#print(html)
html = req.text
# 以lxml 方式进行解析
bs = BeautifulSoup(html,'lxml')

# 我们要获取的标签是 div,而这个 div 的 标识 是 id = 'list'
list = bs.find("div",)
# 通过 这个 div 获取到 内部的 第二个 dt
dt = list.find_all('dt')[1]

# a 标签 列表
aList = []
# url 列表
urlList = []
# name 文章名 列表
nameList = []

# dt.find_all_next('dd') 找到 第二个 dt 标签后 所有的 dd 返回一个 列表
for dd in dt.find_all_next('dd'):
    # 获取每个 dd 标签 内部的 a 标签
    aList.append(dd.find('a'))
    # 获取每个 a 标签 的 href 属性值,即 每一章 的 url
    urlList.append('https://www.yingsx.com'+ dd.find('a').get('href'))
    # 获取每个 a 标签 的 内容,即 每一章 的 标题名
    nameList.append(dd.find('a').text + '.txt')

os.mkdir('元尊')

for i,url in enumerate(urlList):
    req = requests.request(method="GET",url = url)
    req.encoding = 'utf-8'
    html = req.text
    bs = BeautifulSoup(html,'lxml')

    # 找到 content div 标签
    content = bs.find("div",)
    content = content.text.strip().split('\xa0' * 4)

    f = open('元尊\\'+ nameList[i], 'w')
    for str in content:
        f.write(str)
    f.close()
    break

此时我们 又会 犯一个 细节的错误,编码问题!我们知道 我们这个是 中文的小说。所以 写入文件的时候,肯定编码 要 为 utf-8 呀!

Python3 网络爬虫 02 <爬取文字·元尊小说>Python3 网络爬虫 02 <爬取文字·元尊小说>


2.3.1 tqdm 进度条模块 和 成品代码

为了美观,我们最后还是决定 要加一个 下载的进度条。

这里 推荐 大家用 tqdm

Python3 网络爬虫 02 <爬取文字·元尊小说>

-------------------------------------------------成品 代码---------------------------------------------------

import requests
from bs4 import BeautifulSoup
import os
from tqdm import tqdm

# get 方式访问 URL
URL = "https://www.yingsx.com/0_100/"
req = requests.request(method="GET",url=URL)
# 编码调节为 UTF-8
req.encoding = 'utf-8'
#print(html)
html = req.text
# 以lxml 方式进行解析
bs = BeautifulSoup(html,'lxml')

# 我们要获取的标签是 div,而这个 div 的 标识 是 id = 'list'
list = bs.find("div",)
# 通过 这个 div 获取到 内部的 第二个 dt
dt = list.find_all('dt')[1]

# a 标签 列表
aList = []
# url 列表
urlList = []
# name 文章名 列表
nameList = []

# dt.find_all_next('dd') 找到 第二个 dt 标签后 所有的 dd 返回一个 列表
for dd in dt.find_all_next('dd'):
    # 获取每个 dd 标签 内部的 a 标签
    aList.append(dd.find('a'))
    # 获取每个 a 标签 的 href 属性值,即 每一章 的 url
    urlList.append('https://www.yingsx.com'+ dd.find('a').get('href'))
    # 获取每个 a 标签 的 内容,即 每一章 的 标题名
    nameList.append(dd.find('a').text + '.txt')

os.mkdir('元尊')

for i,url in enumerate(tqdm(urlList)):
    req = requests.request(method="GET",url = url)
    req.encoding = 'utf-8'
    html = req.text
    bs = BeautifulSoup(html,'lxml')

    # 找到 content div 标签
    content = bs.find("div",)
    content = content.text.strip().split('\xa0' * 4)

    f = open('元尊\\'+ nameList[i], 'w',encoding='utf-8')
    for str in content:
        f.write(str)
    f.close()

Python3 网络爬虫 02 <爬取文字·元尊小说>


宣传一波 <我自己尝试录制的 从零开始 学习 Python>

配套的 Python 教学视频

相关文章:

  • 2022-01-01
  • 2022-01-01
  • 2021-05-26
  • 2022-02-08
  • 2021-09-12
  • 2022-02-05
  • 2021-10-26
猜你喜欢
  • 2022-01-01
  • 2022-12-23
  • 2021-09-17
  • 2021-06-14
  • 2022-01-01
  • 2021-11-12
相关资源
相似解决方案