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、运行结果

最近更新

  1. TCP协议是安全的吗?

    2024-02-07 20:16:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-07 20:16:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-07 20:16:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-07 20:16:01       18 阅读

热门阅读

  1. Python 字符串追加

    2024-02-07 20:16:01       31 阅读
  2. Elasticsearch单个索引数据量过大的优化

    2024-02-07 20:16:01       41 阅读
  3. C Primer Plus(第六版)15.9 编程练习 第5题

    2024-02-07 20:16:01       33 阅读
  4. [Usaco2008 Feb]Line连线游戏

    2024-02-07 20:16:01       33 阅读
  5. MySQL基础查询篇(10)-正则表达式的基础使用

    2024-02-07 20:16:01       29 阅读
  6. python3实现gitlab备份文件上传腾讯云COS

    2024-02-07 20:16:01       30 阅读
  7. 【Office】或得单元格中以/分隔的后半部分

    2024-02-07 20:16:01       26 阅读