python爬虫7:实战1

python爬虫7:实战1

前言

​ python实现网络爬虫非常简单,只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点,方便以后复习。

申明

​ 本系列所涉及的代码仅用于个人研究与讨论,并不会对网站产生不好影响。

目录结构

文章目录

    • python爬虫7:实战1
      • 1. 目标
      • 2. 详细流程
        • 2.1 找到目标小说
        • 2.2 获取小说章节目录
        • 2.3 获取小说内容
        • 2.4 完整代码
      • 3. 总结

1. 目标

​ 这次爬虫实战,采用的库为:requests + lxml,这次以爬取一部小说为目标,具体的网站老规矩就不给了,大家学习思路最重要。

再次说明,案例本身并不重要,重要的是如何去使用和分析,另外为了避免侵权之类的问题,我不会放涉及到网站的图片,希望能理解

2. 详细流程

2.1 找到目标小说

第一步,确定get请求的url

​ 假设我们的网站为:https://xxxxxxx.com,那么,我们首先需要找到搜索框,然后随意搜索几本小说,比如这里我搜索的是圣墟万族之劫,那么观察网页上的url变化,如下:

https://xxxxx?q=圣墟
https://xxxxx?q=万族之劫

​ 可以看出,这里是get请求,并且参数名为q

第二步,正确请求网页

​ 我们可以写下第一个代码了,目标是获取想要的小说,代码如下:

# 都要用到的参数
HEADERS = {
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
}

# 获取搜索某小说后的页面
def get_search_result():
    # 网址
    url = 'xxxxx'
    # 请求参数
    search = input('请输入想要搜索的小说:')
    params = {
        'q' : search
    }
    # 请求
    response = requests.get(url,headers=HEADERS,params=params)
    # 把获取到的网页保存到本地
    with open('search.html','w',encoding='utf-8') as f:
        f.write(response.content.decode('utf-8'))

​ 结果如下:

在这里插入图片描述

​ 可以看出,获取到正确的网页,说明这一步我们完成了

正确解析网页,以获取小说链接

​ 上面,我们已经把网页源码存放到了本地一个名为search.html的文件,下面我们来解析它。

​ 解析它,首先需要明确我们要获取什么节点、什么值。看下面:

在这里插入图片描述

​ 可以看出,我们的目标标签位于div[class="mshow"]下的table[class="grid"]下的td下的a标签,并且我们需要获取这个a标签的href属性和文本值。除此之外,href属性值只是部分地址,需要跟网站根地址xxxx.com拼凑再一起。

​ 基于此,可以完成代码:

# 解析网页
def parse_search_result():
    # 打开文件,读取文件
    with open('search.html','r',encoding='utf-8') as f:
        content = f.read()
        # 基础url
        base_url = 'xxxxxx.com/'
        # 初始化lxml
        html = etree.HTML(content)
        # 获取目标节点
        href_list = html.xpath('//div[@class="show"]//table[@class="grid"]//td//a/@href')
        text_list = html.xpath('//div[@class="show"]//table[@class="grid"]//td//a/text()')
        # 处理内容值
        url_list = [base_url+href  for href in href_list]
        # 选择要爬取的小说
        for i,text in enumerate(text_list):
            print('当前小说名为:',text)
            decision = input('是否爬取它(只能选择一本),Y/N:')
            if decision == 'Y':
                return url_list[i],text

​ 运行结果如下:

在这里插入图片描述

2.2 获取小说章节目录

第一步,请求页面

​ 首先,我们去请求上面获取的网页,这里就比较简单了,基本上把上面的请求代码拷贝过来修改修改即可:

# 请求目标小说网站
def get_target_book(url):
    # 请求
    response = requests.get(url,headers=HEADERS)
    # 保存源码
    with open('book.html','w',encoding='utf-8') as f:
        f.write(response.content.decode('utf-8'))

​ 可以看到保存到本地的结果如下:
在这里插入图片描述

可以看出,这一步成功了

第二步,解析上面的网页,获取不同章节的链接

​ 这一步,主要的难点在于解析网页,首先,看下面:

在这里插入图片描述

​ 由于该网页小说章节都分为两个部位,第一个为最新章节,第二个为全部章节,而第二个才是我们需要获取的,因此xpath语法应该为:

//div[@class="show"]//div[contains(@class,'showBox') and position()=3]//ul//a

​ 那么,可以完成代码如下:

# 解析章节网页
def parse_chapter(base_url):
    # 打开文件,读取内容
    with open('book.html','r',encoding='utf-8') as f:
        content = f.read()
        # 初始化
        html = etree.HTML(content)
        # 解析
        href_list = html.xpath('//div[@class="show"]//div[contains(@class,"showBox") and position()=3]//ul//a/@href')
        text_list = html.xpath('//div[@class="show"]//div[contains(@class,"showBox") and position()=3]//ul//a/text()')
        # 处理:拼凑出完整网页
        url_list = [base_url+url for url in href_list]
        # 返回结果
        return url_list,text_list

​ 运行结果如下:

在这里插入图片描述

2.3 获取小说内容

​ 这里我们就不分开了,直接获取源码后直接解析。那么这里说明一下解析原理,看下面:

在这里插入图片描述

​ 可以轻松知道xpath语法:

//div[contains(@class,'book')]//div[@id='content']//text()

​ 那么,代码如下:

# 请求小说页面
def get_content(url,title):
    # 请求
    response = requests.get(url,headers=HEADERS)
    # 获取源码
    content = response.content.decode('utf-8')
    # 初始化
    html = etree.HTML(content)
    # 解析
    text_list = html.xpath('//div[contains(@class,"book")]//div[@id="content"]//text()')
    # 后处理
    # 首先,把第一个和最后一个的广告信息去掉
    text_list = text_list[1:-1]
    # 其次,把里面的空白字符和\xa0去掉
    text_list = [text.strip().replace('\xa0','') for text in text_list]
    # 最后,写入文件即可
    with open(title+'.txt','w',encoding='utf-8') as g:
        for text in text_list:
            g.write(text+'\n')

​ 运行结果如下:

在这里插入图片描述

可以看出,成功实现

2.4 完整代码

​ 完整代码如下:

# author : 自学小白菜
# -*- coding:utf-8 -*-

'''
# File Name : 7 lxml_novel.py
# Create Time : 2023/8/5 22:04
# Version : python3.7
# Description :  实战1:爬取小说
'''

# 导包
import requests
from lxml import etree

# 都要用到的参数
HEADERS = {
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
}

# 获取搜索某小说后的页面
def get_search_result():
    # 网址
    url = 'https://www.iwurexs.net/so.html'
    # 请求参数
    search = input('请输入想要搜索的小说:')
    params = {
        'q' : search
    }
    # 请求
    response = requests.get(url,headers=HEADERS,params=params)
    # 把获取到的网页保存到本地
    with open('search.html','w',encoding='utf-8') as f:
        f.write(response.content.decode('utf-8'))

# 解析网页
def parse_search_result():
    # 打开文件,读取文件
    with open('search.html','r',encoding='utf-8') as f:
        content = f.read()
        # 基础url
        base_url = 'https://www.iwurexs.net/'
        # 初始化lxml
        html = etree.HTML(content)
        # 获取目标节点
        href_list = html.xpath('//div[@class="show"]//table[@class="grid"]//td//a/@href')
        text_list = html.xpath('//div[@class="show"]//table[@class="grid"]//td//a/text()')
        # 处理内容值
        url_list = [base_url+href  for href in href_list]
        # 选择要爬取的小说
        for i,text in enumerate(text_list):
            print('当前小说名为:',text)
            decision = input('是否爬取它(只能选择一本),Y/N:')
            if decision == 'Y':
                return url_list[i],text

# 请求目标小说网站
def get_target_book(url):
    # 请求
    response = requests.get(url,headers=HEADERS)
    # 保存源码
    with open('book.html','w',encoding='utf-8') as f:
        f.write(response.content.decode('utf-8'))

# 解析章节网页
def parse_chapter(base_url):
    # 打开文件,读取内容
    with open('book.html','r',encoding='utf-8') as f:
        content = f.read()
        # 初始化
        html = etree.HTML(content)
        # 解析
        href_list = html.xpath('//div[@class="show"]//div[contains(@class,"showBox") and position()=3]//ul//a/@href')
        text_list = html.xpath('//div[@class="show"]//div[contains(@class,"showBox") and position()=3]//ul//a/text()')
        # 处理:拼凑出完整网页
        url_list = [base_url+url for url in href_list]
        # 返回结果
        return url_list,text_list

# 请求小说页面
def get_content(url,title):
    # 请求
    response = requests.get(url,headers=HEADERS)
    # 获取源码
    content = response.content.decode('utf-8')
    # 初始化
    html = etree.HTML(content)
    # 解析
    text_list = html.xpath('//div[contains(@class,"book")]//div[@id="content"]//text()')
    # 后处理
    # 首先,把第一个和最后一个的广告信息去掉
    text_list = text_list[1:-1]
    # 其次,把里面的空白字符和\xa0去掉
    text_list = [text.strip().replace('\xa0','') for text in text_list]
    # 最后,写入文件即可
    with open(title+'.txt','w',encoding='utf-8') as g:
        for text in text_list:
            g.write(text+'\n')

if __name__ == '__main__':
    # 第一步,获取到搜索页面的源码
    # get_search_result()
    # 第二步,进行解析
    target_url,name = parse_search_result()
    # 第三步,请求目标小说页面
    get_target_book(target_url)
    # 第四步,解析章节网页
    url_list,text_list = parse_chapter(target_url)
    for url,title in zip(url_list,text_list):
        # 第五步,请求小说具体的某个章节并直接解析
        get_content(url,title)
        break

3. 总结

​ 上面代码还不完善,存在一定优化的地方,比如代码有些地方可以解耦,另外,必须限制访问速度,不然后期容易被封掉IP,除此之外,可以考虑代理池构建等操作。

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

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

相关文章

Unity 鼠标实现对物体的移动、缩放、旋转

文章目录 1. 代码2. 测试场景 1. 代码 using UnityEngine;public class ObjectManipulation : MonoBehaviour {// 缩放比例限制public float MinScale 0.2f;public float MaxScale 3.0f;// 缩放速率private float scaleRate 1f;// 新尺寸private float newScale;// 射线pri…

RDMA qp数量和RDMA性能

QP数量上升性能下降 ​​​​​​https://icnp21.cs.ucr.edu/papers/icnp21camera-paper30.pdf 在现代云数据中心中,大规模分布式应用通常构建在许多机器上,需要使用大量并发连接进行频繁的网络通信[4]–[6]。但是,RDMA的性能会随着连接数的…

购买steam余额有风险吗?以及N种被红锁的情况

购买steam余额有风险吗?以及N种被红锁的情况 无论是打游戏的玩家,还是像我们这类靠倒卖装备赚钱的小商贩,都面临充值美金余额的问题,我们现在主要是找的专业充值渠道做代充。 最近我发现群里有极个别学员通过自己的方法找到了一…

菜鸟Vue教程 - 实现带国际化的注册登陆页面

初接触vue的时候觉得vue好难,因为项目中要用到,就硬着头皮上,慢慢的发现也不难,无外乎画个布局,然后通过样式调整界面。在通过属性和方法跟js交互。js就和我们写的java代码差不多了,复杂一点的就是引用这种…

“智能查单轻松实现批量快递查询,高效掌握快递物流信息!“

亲爱的用户,你是否常常为了查询大量快递单号而感到烦恼?不用担心,我们已经为你提供了一种高效、智能的解决方案!现在,只需一键操作,即可实现批量快递查询,迅速了解每个单号的详细物流信息。 首…

代码随想录算法训练营第三十九天 | 62.不同路径,63. 不同路径 II

代码随想录算法训练营第三十九天 | 62.不同路径,63. 不同路径 II 62.不同路径深搜动态规划数论方法:eyes:题目总结:eyes: 63. 不同路径 II:eyes:题目总结:eyes: 62.不同路径 题目链接 视频讲解 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标…

爬虫逆向实战(八)--猿人学第十五题

一、数据接口分析 主页地址:猿人学第十五题 1、抓包 通过抓包可以发现数据接口是api/match/15 2、判断是否有加密参数 请求参数是否加密? 查看“载荷”模块可以发现有一个m加密参数 请求头是否加密? 无响应是否加密? 无cook…

JavaScript(JavaEE初阶系列13)

目录 前言: 1.初识JavaScript 2.JavaScript的书写形式 2.1行内式 2.2内嵌式 2.3外部式 2.4注释 2.5输入输出 3.语法 3.1变量的使用 3.2基本数据类型 3.3运算符 3.4条件语句 3.5循环语句 3.6数组 3.7函数 3.8对象 3.8.1 对象的创建 4.案例演示 4…

05_bitmaphyperloglogGEO

Bitmap&hyperloglog&GEO 面试问 记录对集合中的数据进行统计在移动应用中,需要统计每天的新增用户数和第2天的留存用户数;在电商网站的商品评论中,需要统计评论列表中的最新评论:在签到打卡中,需要统计一个月内…

PHP8的正则表达式-PHP8知识详解

在网页程序的时候,经常会有查找符合某些复杂规则的字符串的需求。正则表达式就是描述这些规则的工具。 正则表达式是把文本或者字符串按照一定的规范或模型表示的方法,经常用于文本的匹配操作。 例如:我们在填写手机号码的时候,…

【编织时空四:探究顺序表与链表的数据之旅】

本章重点 链表的分类 带头双向循环链表接口实现 顺序表和链表的区别 缓存利用率参考存储体系结构 以及 局部原理性。 一、链表的分类 实际中链表的结构非常多样,以下情况组合起来就有8种链表结构: 1. 单向或者双向 2. 带头或者不带头 3. 循环或者非…

PHP8的字符串操作3-PHP8知识详解

今天继续分享字符串的操作,前面说到了字符串的去除空格和特殊字符,获取字符串的长度,截取字符串、检索字符串。 今天继续分享字符串的其他操作。如:替换字符串、分割和合成字符串。 5、替换字符串 替换字符串就是对指定字符串中…

改进YOLO系列:3.添加SOCA注意力机制

添加SOCA注意力机制 1. SOCA注意力机制论文2. SOCA注意力机制原理3. SOCA注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置1. SOCA注意力机制论文 暂未找到 2. SOCA注意力机制原理 3. SOCA注意力机制的配置 3.1common.py配置 ./models/common.p…

C#程序随系统启动例子 - 开源研究系列文章

今天讲讲C#中应用程序随系统启动的例子。 我们知道,应用程序随系统启动,都是直接在操作系统注册表中写入程序的启动参数,这样操作系统在启动的时候就根据启动参数来启动应用程序,而我们要做的就是将程序启动参数写入注册表即可。此…

react-native-webview使用postMessage后H5不能监听问题(iOS和安卓的兼容问题)

/* 监听rn消息 */ const eventListener nativeEvent > {//解析数据actionType、extraconst {actionType, extra} nativeEvent.data && JSON.parse(nativeEvent.data) || {} } //安卓用document,ios用window window.addEventListener(message, eventLis…

SASS 学习笔记 II

SASS 学习笔记 II 上篇笔记,SASS 学习笔记 中包含: 配置 变量 嵌套 这里加一个扩展,嵌套中有一个 & 的用法,使用 & 可以指代当前 block 中的 selector,后面可以追加其他的选择器。如当前的 scope 是 form&a…

02-C++数据类型-高级

数据类型-高级 4、复合类型 4.4、结构简介 struct inflatable {char name[20];float vol;double price; };inflatable vincent; //C struct inflatable goose; //C例子 // structur.cpp -- a simple structure #include <iostream> struct inflatable // structu…

17万字数字化医院信息化建设大数据平台建设方案WORD

导读&#xff1a;原文《17万字数字化医院信息化建设大数据平台建设方案WORD》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 目录 第1章 医院信息化概述 1.1 国内…

Spring的生命周期及Spring Bean单例和多例---超详细教学

一&#xff0c;何为spring生命周期 一个Bean对象从被Spring容器创建到被销毁的整个过程。Spring框架对Bean对象的生命周期进行了管理&#xff0c;提供了灵活性和控制权&#xff0c;让开发人员能够在不同的阶段进行自定义操作 1.1生命周期图 1.2.为什么要学习对象的生命周期…

PyTorch训练深度卷积生成对抗网络DCGAN

文章目录 DCGAN介绍代码结果参考 DCGAN介绍 将CNN和GAN结合起来&#xff0c;把监督学习和无监督学习结合起来。具体解释可以参见 深度卷积对抗生成网络(DCGAN) DCGAN的生成器结构&#xff1a; 图片来源&#xff1a;https://arxiv.org/abs/1511.06434 代码 model.py impor…