Python进阶--爬取下载人生格言(基于格言网的Python3爬虫)

目录

一、此处需要安装第三方库:

二、抓包分析及Python代码 

1、打开人生格言网(人生格言-人生格言大全_格言网)进行抓包分析

2、请求模块的代码

3、抓包分析人生格言界面

4、获取各种类型的人生格言链接

5、获取下一页的链接

6、获取人生格言的具体内容

7、 下载保存

 三、所有代码及具体步骤

1、具体步骤

2、所有代码如下:

3、运行结果


一、此处需要安装第三方库:

        在Pycharm平台终端或者命令提示符窗口中输入以下代码即可安装

pip install requests
pip install lxml
  •  requests模块为请求库
  • lxml库是一个HTML/XML的解析器,主要的功能是解析和提取 HTML/XML 数据

        注: 此处需要用到xPath和正则表达式的知识,关于xPath和正则表达式,此处不进行详细说明,后续我将补充一篇博客来详细介绍。

二、抓包分析及Python代码 

1、打开人生格言网(人生格言-人生格言大全_格言网)进行抓包分析

        此处下载的是文字,格言网是一个静态网页,人生格言的信息全都封装在源代码中,故此主要针对网页源代码进行分析爬取。不过首先要获取到网页内容的源代码,故此处采用requests模块的get方法即可。使用get方法,需要抓包分析获取url和user-agent即可。

  • url和user-agent的获取方法:
  1. 打开格言网中的人生格言网站
  2. 按下F12键,打开开发者界面
  3. 此时由于页面没有数据传输,属于静态页面,开发者界面也就没有任何数据传输的情况。
  4. 刷新一下,在开发者界面点击Network,选择all,点击第一个html文件信息条目,在header视图中可以找到url信息和user-agent信息

url:

user-agent:

2、请求模块的代码

import requests
header = {'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Mobile Safari/537.36'}
url = 'http://www.mouxiao.com/renshenggeyan/index.html'
response = requests.get(url, headers=header)
print(response)

3、抓包分析人生格言界面

在人生格言界面,可以看到:

  • 有多种类型的人生格言,点击其中一个即可跳转到其具体的格言内容中
  • 有下一页的选项,点击下一页则跳转到下一页的多种类型的人生格言
  • 下面还有其他栏目导航

        这里,需要下载的是所有的人生格言,即需要将人生格言栏目中的所有类型的人生格言全都下载下来。每种类型和下一页是通过跳转的方式,访问到具体内容的。而跳转是通过链接的方式进行的。故只需要抓包分析,分析出链接所在位置,获取到这些链接。即可再通过requests请求模块,访问这些链接来下载具体的人生格言内容。

  • 抓包分析:

        采用以上抓包方式,具体查找一下其他类型的链接所在位置。通过以上操作可以分析出链接都是藏标签<li>中的标签<a>中的href属性中且链接是以数字开头的,在此处采用xPath的方式,获取这些类型的所有的链接。

4、获取各种类型的人生格言链接

根据以上分析,获取各种类型的人生格言的链接代码如下:

import pprint

import requests
from lxml import etree
header = {'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Mobile Safari/537.36'}
index_url = 'http://www.mouxiao.com/renshenggeyan/index.html'
r = requests.get(index_url,headers=header)
# 由于requests模块会将获取的网页源代码进行自动编码,此处我们不需要编码。
# 故采用apparent_encoding方法,禁止requests模块自动编码。
r.encoding = r.apparent_encoding
# 采用xpath的方式定位获取链接所在位置
html = etree.HTML(r.text)
links = html.xpath('//ul[@class="readers-list"]//a/@href')
# 采用格式化打印,打印一下links内容
pprint.pprint(links)

运行结果如下(部分图):

        根据上面的抓包分析,所需要的链接是以数字开头,但运行结果中却出现了大量不以数字开头的链接。这是为什么?继续抓包分析:

        我们发现栏目导航部分中的链接所在位置跟上面抓包分析的各种类型的人生格言的链接所在位置是一致的。所以使用xPath定位链接时,把栏目导航中的链接也定位到了,但我们不需要栏目导航中的链接。根据前面分析,可知我们需要的链接是以数字开头的。则,可以采用正则表达式,筛选出所需的链接。代码如下:

import pprint
import re

import requests
from lxml import etree
header = {'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Mobile Safari/537.36'}
index_url = 'http://www.mouxiao.com/renshenggeyan/index.html'
r = requests.get(index_url,headers=header)
# 由于requests模块会将获取的网页源代码进行自动编码,此处我们不需要编码。
# 故采用apparent_encoding方法,禁止requests模块自动编码。
r.encoding = r.apparent_encoding
# 采用xpath的方式定位获取链接所在位置
html = etree.HTML(r.text)
links = html.xpath('//ul[@class="readers-list"]//a/@href')
# 要匹配所有以数字开头,后面跟 '.html' 的元素,可以遍历列表
matched_links = []
for link in links:
    # 采用正则表达式筛选出我们所需要的链接,将其保存到matched_links中
    if re.findall(r'^\d+\.html', link):
        matched_links.append(link)
# 采用格式化打印,打印一下links内容
pprint.pprint(matched_links)

结果如下:

此处,成功获取到所需目录页中各种类型的人生格言的链接了。(非常开心!!!)

5、获取下一页的链接

        根据上面分析,因为点击下一页跳转的出现的界面还有其他类型的人生格言,故下一页也需要获取其链接。因为,这样就可以通过下一页,来继续获取根据上面的抓包方式,可以定位到下一页的链接所在位置。通过xPath的方式,定位获取得到。

 代码如下:

# 封装成一个函数,输入当前页面的url,返回下一页的url
def get_nextpage(url):
    #请求当前网页的源代码
    r = requests.get(url, headers=header)
    # 拒绝requests的自动编码,保留源代码
    r.encoding = r.apparent_encoding
    # 定位到下一页的url地址
    html = etree.HTML(r.text)
    next_page = html.xpath('//div[@class="maike"]//p[@class="p"]//a/@href')[3]
    # 因为所获取的下一页地址是相对地址,故进行补全
    next_page = 'http://www.mouxiao.com/renshenggeyan/'+ next_page
    # 如果下一页地址和当前页地址不相等,则将下一页地址返回
    if next_page != url:
        return next_page

6、获取人生格言的具体内容

        当点击进入一个类型的人生格言,我们会进入到该类型的具体人生格言内容。

对其抓包分析:

        据此,我们定位到了标题和具体人生格言的所在网页源代码的位置。采用xPath方式,进行定位。代码如下:

# 封装成一个函数,输入具体人生格言页的地址,获取其具体的人生格言和标题
def get_content(url):
    # 请求当前网页的源代码
    r = requests.get(url,headers=header)
    # 拒绝requests的自动编码,保留源代码
    r.encoding = r.apparent_encoding
    # 解析源代码提取具体格言内容和标题
    # 获取网页源代码
    html = etree.HTML(r.text)
    # 获取格言内容
    content = html.xpath('//div[@class="maike"]/p[@class="p"]/text()')
    # 使用 join() 方法将列表中的元素用换行符连接起来
    content = '\n'.join(content)
    # 获取标题
    title = html.xpath('//div[@class="maike"]/h1[@class="title_l"]/text()')[0]
    return title,content

7、 下载保存

        根据以上内容,已经获取到了人生格言的具体内容和标题的函数--get_content。只需要将具体人生格言页的链接输入进去,调用get_content函数,采用open方法即可进行下载保存。

        title, content = get_content(link1)
        with open(f'格言/{title}.txt','w',encoding='utf-8') as f:
            f.write('\t'+title + '\n\n')
            f.write(content)
            print(f'已下载...{title}')

 三、所有代码及具体步骤

1、具体步骤

1、获取格言页网页源代码
2、提取格言内容 
3、获取目录页网页源代码
4、解析目录页,提取链接(各种类型的人生格言链接和下一页链接)
5、下载并保存所有格言

2、所有代码如下:

import re
import requests
from lxml import etree
# 获取user-agent,用于身份识别
header = {'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Mobile Safari/537.36'}
# 1、获取具体格言内容和标题
# 封装成一个函数,输入具体人生格言页的地址,获取其具体的人生格言和标题
def get_content(url):
    # 请求当前网页的源代码
    r = requests.get(url,headers=header)
    # 拒绝requests的自动编码,保留源代码
    r.encoding = r.apparent_encoding
    # 解析源代码提取具体格言内容和标题
    # 获取网页源代码
    html = etree.HTML(r.text)
    # 获取格言内容
    content = html.xpath('//div[@class="maike"]/p[@class="p"]/text()')
    # 使用 join() 方法将列表中的元素用换行符连接起来
    content = '\n'.join(content)
    # 获取标题
    title = html.xpath('//div[@class="maike"]/h1[@class="title_l"]/text()')[0]
    # 返回标题和内容
    return title,content
# 当前页面
index_url = 'http://www.mouxiao.com/renshenggeyan/index.html'
# 2、获取各种类型的人生格言链接并下载其具体人生格言内容和标题
# 输入当前人生格言的目录页地址,获取各种类型的人生格言链接并下载其具体人生格言内容和标题
def pageupload_play(index_url):
    # 请求当前网页的源代码
    r = requests.get(index_url,headers=header)
    # 由于requests模块会将获取的网页源代码进行自动编码,此处我们不需要编码。
    # 故采用apparent_encoding方法,禁止requests模块自动编码。
    r.encoding = r.apparent_encoding
    # 采用xpath的方式定位获取链接所在位置
    html = etree.HTML(r.text)
    links = html.xpath('//ul[@class="readers-list"]//a/@href')
    # 要匹配所有以数字开头,后面跟 '.html' 的元素,可以遍历列表
    matched_links = []
    for link in links:
        # 采用正则表达式筛选出我们所需要的链接,将其保存到matched_links中
        if re.findall(r'^\d+\.html', link):
            matched_links.append(link)
    # 遍历每个类型人生格言的具体人生格言内容和标题,对其进行下载
    for link in matched_links:
        # link中获取的链接是相对地址,需要补全前面的地址
        link1 = 'http://www.mouxiao.com/renshenggeyan/'+link
        # 调用get_content方法下载内容和标题并保存到本地
        title, content = get_content(link1)
        with open(f'格言/{title}.txt','w',encoding='utf-8') as f:
            f.write('\t'+title + '\n\n')
            f.write(content)
            print(f'已下载...{title}')
# 3、获取下一页的地址
# 封装成一个函数,输入当前页面的url,返回下一页的url
def get_nextpage(url):
    #请求当前网页的源代码
    r = requests.get(url, headers=header)
    # 拒绝requests的自动编码,保留源代码
    r.encoding = r.apparent_encoding
    # 定位到下一页的url地址
    html = etree.HTML(r.text)
    next_page = html.xpath('//div[@class="maike"]//p[@class="p"]//a/@href')[3]
    # 因为所获取的下一页地址是相对地址,故进行补全
    next_page = 'http://www.mouxiao.com/renshenggeyan/'+ next_page
    # 如果下一页地址和当前页地址不相等,则将下一页地址返回
    if next_page != url:
        return next_page
# 4、将以上函数排放好顺序进行调用,下载人生格言的全部内容及标题
n = 1
while 1:
    print(f"正在下载第{n}页...")
    print("下载地址为:"+index_url)
    pageupload_play(index_url)
    page = get_nextpage(index_url)
    index_url = page
    if index_url==None:
        break
    n+=1

3、运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/376609.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

最新话费充值系统源码,附带系统安装教程

搭建教程 亲测环境&#xff1a;PHP7.0MySQL5.6 PHP扩展安装&#xff1a;sg11 数据库配置文件路径&#xff1a;/config/database.php 伪静态设置为thinkphp 后台地址&#xff1a;/admin 账号密码&#xff1a;admin/123456

SpringBoot源码解读与原理分析(八)ApplicationContext

文章目录 3.1.2 ApplicationContext3.1.2.1 ApplicationContext根接口3.1.2.2 ConfigurableApplicationContext3.1.2.3 EnvironmentCapable3.1.2.4 MessageSource3.1.2.5 ApplicationEventPublisher3.1.2.6 ResourcePatternResolver3.1.2.7 AbstractApplicationContext3.1.2.8 …

当我们一起走过 2023|Apache Doris 年度时刻盘点

2024 年的第一个月已经彻底过去&#xff0c;2023 年的回顾总结才姗姗来迟。 在过去一年的大多数时间里&#xff0c;我们一直处于忙碌的状态中&#xff0c;紧锣密鼓的代码研发、高速推进的版本迭代、行程紧密的全国之行&#xff0c;众多社区用户与开发者皆是见证。 越是忙碌&a…

Yearning审核平台本地安装配置并结合内网穿透实现远程访问

文章目录 前言1. Linux 部署Yearning2. 本地访问Yearning3. Linux 安装cpolar4. 配置Yearning公网访问地址5. 公网远程访问Yearning管理界面6. 固定Yearning公网地址 前言 Yearning 简单, 高效的MYSQL 审计平台 一款MYSQL SQL语句/查询审计工具&#xff0c;为DBA与开发人员使用…

vector类的模拟实现

实现基本的vector框架 参考的是STL的一些源码&#xff0c;实现的vector也是看起来像是一个简略版的&#xff0c;但是看完能对vector这个类一些接口函数更好的认识。 我们写写成员变量&#xff0c;先来看看STL的成元变量是那些 namespace tjl {template<class T>class …

【C语言|数据结构】数据结构顺序表

目录 一、数据结构 1.1概念 1.2总结 1.3为什么需要数据结构&#xff1f; 二、顺序表 1.顺序表的概念及结构 1.1线性表 2.顺序表分类 2.1顺序表和数组的区别 2.2顺序表的分类 2.2.1静态顺序表 2.2.1.1概念 2.2.1.2缺陷 2.2.2动态顺序表 三、动态顺序表的实现 3.1新…

Pandas文本数据处理技术指南—从查找到时间序列分析【第66篇—python:文本数据处理】

文章目录 Pandas文本数据处理技术指南引言 1. 查找文本数据2. 替换文本数据3. 拼接文本数据4. 正则表达式操作5. 虚拟变量6. 处理缺失值7. 分割文本数据8. 字符串处理方法9. 文本数据的合并与连接10. 文本数据的排序11. 文本数据的统计分析12. 文本数据的分组与聚合13. 文本数据…

使用Softing edgeConnector模块将云轻松连接到Siemens PLC

一 工业边缘的连接解决方案 云服务提供商 (CSP) 引入了服务和功能&#xff0c;以简化基于云的工业物联网解决方案的实施。Azure Industrial IoT Platform或AWS IoT SiteWise支持标准协议和接口&#xff0c;例如OPC UA或MQTT。但是&#xff0c;如果您希望在典型的旧改项目中连接…

【代理模式】

定义&#xff1a;代理模式是一种结构型设计模式&#xff0c;它允许我们创建一个代理对象&#xff0c;用于控制对另一个对象的访问。 代理对象充当了被代理对象&#xff08;目标对象&#xff09;的代表&#xff0c;与被代理对象实现相同的接口&#xff0c;从而实现对被代理对象…

【PowerShell】修改Windows网络配置的常用命令

PowerShell&#xff08;PS&#xff09;是一种强大的任务自动化和管理框架&#xff0c;具有丰富的命令和语法&#xff0c;可以用于编写脚本来管理Windows操作系统和其他应用程序。它的开放式架构和跨平台支持使得它成为一个灵活和可扩展的工具。 在网络配置方面&#xff0c;Powe…

C++ 日期计算器

日期计算器 概要 Date类的规划Date类的实现Date 构造函数Date 拷贝构造函数~Date 析构函数GetMonthDay 求某年某月的天数operator 赋值操作符重载operator 加等操作符重载operator 加号操作符重载operator- 减等操作符重载operator- 减法操作符重载 &#xff08;日期 - 天数&am…

分享66个行业PPT,总有一款适合您

分享66个行业PPT&#xff0c;总有一款适合您 66个行业PPT下载链接&#xff1a;https://pan.baidu.com/s/1kcUOfR_xtH9CAJC12prcTw?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易。知…

算法学习——华为机考题库3(HJ21 - HJ25)

算法学习——华为机考题库3&#xff08;HJ21 - HJ30&#xff09; HJ21 简单密码 描述 现在有一种密码变换算法。 九键手机键盘上的数字与字母的对应&#xff1a; 1–1&#xff0c; abc–2, def–3, ghi–4, jkl–5, mno–6, pqrs–7, tuv–8 wxyz–9, 0–0&#xff0c;把密码…

Swift Combine 发布者订阅者操作者 从入门到精通二

Combine 系列 Swift Combine 从入门到精通一 1. Combine核心概念 你只需要了解几个核心概念&#xff0c;就能使用好 Combine&#xff0c;但理解它们非常重要。 这些概念中的每一个都通过通用协议反映在框架中&#xff0c;以将概念转化为预期的功能。 这些核心概念是&#x…

Cocos creator 3.x 刚体组件碰撞无效

Cocos creator 3.x 刚体组件碰撞无效 问题描述&#xff1a;只有一个circleCollider2D时&#xff0c;可以在碰撞时正确输出结果&#xff0c;但是当我在外围加了一个circle之后&#xff0c;期望character进入圆圈范围时就触发方法&#xff0c;此时原代码失效 import { _decorat…

简单说网络:TCP+UDP

TCP和UPD: (1)都工作在传输层 (2)目的都是在程序之中传输数据 (3)数据可以是文本、视频或者图片(对TCP和UDP来说都是一堆二进制数没有太大区别) 一、区别:一个基于连接一个基于非连接 将人与人之间的通信比喻为进程和进程之前的通信:基本上有两种方式(1)写信;(2)打电话;这…

【51单片机】实现一个动静态数码管显示项目(前置知识铺垫,代码&图演示)(5)

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY…

Redis的数据类型Hash使用场景实战

Redis的数据类型Hash使用场景 常见面试题&#xff1a;redis在你们项目中是怎么用的&#xff0c;除了String数据类型还使用什么数据类型&#xff1f; 怎么保证缓存和数据一致性等问题… Hash模型使用场景 知识回顾&#xff1a; redisTemplate.opsForHash() 方法是 Redis 的 …

QAnything之BCEmbedding技术路线

QAnything和BCEmbedding简介 QAnything[github]是网易有道开源的检索增强生成式应用&#xff08;RAG&#xff09;项目&#xff0c;在有道许多商业产品实践中已经积累丰富的经验&#xff0c;比如有道速读和有道翻译。QAnything是一个支持任意格式文件或数据库的本地知识库问答系…