python爬虫9:实战2

python爬虫9:实战2

前言

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

申明

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

目录结构

文章目录

    • python爬虫9:实战2
      • 1. 目标
      • 2. 详细流程
        • 2.1 前置说明
        • 2.2 修改1:目标小说获取解析函数修改
        • 2.3 修改2:章节目录获取解析函数修改
        • 2.4 修改3:获取小说内容解析函数修改
        • 2.5 完整代码:
      • 3. 总结

1. 目标

​ 这次爬虫实战,采用的库为:requests + bs4,这次的案例来自于python爬虫7:实战1这篇文章,本次主要的点在于利用bs4进行解析,因此,建议大家先阅读python爬虫7:实战1,因为里面的代码我会直接拷贝过来用。

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

2. 详细流程

2.1 前置说明

​ 由于不需要重新写大部分代码,因此本篇主要讲解一下如何用bs4去解析网页。

​ 这里先把之前的代码拷贝过来:

# 导包
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()# 基础urlbase_url = 'https://www.iwurexs.net/'# 初始化lxmlhtml = 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

​ 其中需要修改的部分有:三个解析函数

2.2 修改1:目标小说获取解析函数修改

​ 本次要修改的函数名为parse_search_result

​ 那么,看下图:

在这里插入图片描述

​ 那么,我们可以这么去寻找a标签:

1. 找到table标签,其class="grid"
2. 找到table下的a标签即可

​ 那么,代码修改如下:

# 解析网页
def parse_search_result():# 打开文件,读取文件with open('search.html', 'r', encoding='utf-8') as f:content = f.read()# 基础urlbase_url = 'https://www.iwurexs.net/'# 初始化lxmlsoup = BeautifulSoup(content,'lxml')# 获取目标节点a_list = soup.find_all('table',attrs={'class':'grid'})[0].find_all('a')url_list = [base_url + a['href'] for a in a_list]text_list = [a.string for a in a_list]# 选择要爬取的小说for i,text in enumerate(text_list):print('当前小说名为:',text)decision = input('是否爬取它(只能选择一本),Y/N:')if decision == 'Y':return url_list[i],text

​ 运行结果如下:

在这里插入图片描述

2.3 修改2:章节目录获取解析函数修改

​ 本次要修改的函数名为parse_chapter

​ 首先,还是看下图:

在这里插入图片描述

​ 那么,可以这么进行解析:

1. 首先,获取所有含有class="showBox"的div标签,共三个,但是我们只要第三个
2. 其次,获取该div下的所有a标签即可

​ 那么,代码修改如下:

# 解析章节网页
def parse_chapter(base_url):# 打开文件,读取内容with open('book.html', 'r', encoding='utf-8') as f:content = f.read()# 初始化soup = BeautifulSoup(content,'lxml')# 解析# 获取最后一个div标签div_label = soup.find_all('div',attrs={'class':'showBox'})[-1]# 获取所有a标签a_list = div_label.find_all('a')# 获取内容url_list = [base_url+a['href'] for a in a_list]text_list = [a.string for a in a_list]# 返回结果return url_list,text_list

​ 运行结果如下:

在这里插入图片描述

2.4 修改3:获取小说内容解析函数修改

​ 本次要修改的函数名为get_content

​ 首先,还是看下图:

在这里插入图片描述

​ 那么,可以这么进行解析:

1. 直接获取id=“content”的div标签
2. 在获取其下的所有内容

​ 那么,修改代码如下:

# 请求小说页面
def get_content(url,title):# 请求response = requests.get(url,headers=HEADERS)# 获取源码content = response.content.decode('utf-8')# 初始化soup = BeautifulSoup(content,'lxml')# 解析text_list = list(soup.find_all('div',attrs={'id':'content'})[0].stripped_strings)# 后处理# 首先,把第一个和最后一个的广告信息去掉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.5 完整代码:

# 导包
import requests
from bs4 import BeautifulSoup# 都要用到的参数
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()# 基础urlbase_url = 'https://www.iwurexs.net/'# 初始化lxmlsoup = BeautifulSoup(content,'lxml')# 获取目标节点a_list = soup.find_all('table',attrs={'class':'grid'})[0].find_all('a')url_list = [base_url + a['href'] for a in a_list]text_list = [a.string for a in a_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()# 初始化soup = BeautifulSoup(content,'lxml')# 解析# 获取最后一个div标签div_label = soup.find_all('div',attrs={'class':'showBox'})[-1]# 获取所有a标签a_list = div_label.find_all('a')# 获取内容url_list = [base_url+a['href'] for a in a_list]text_list = [a.string for a in a_list]# 返回结果return url_list,text_list# 请求小说页面
def get_content(url,title):# 请求response = requests.get(url,headers=HEADERS)# 获取源码content = response.content.decode('utf-8')# 初始化soup = BeautifulSoup(content,'lxml')# 解析text_list = list(soup.find_all('div',attrs={'id':'content'})[0].stripped_strings)# 后处理# 首先,把第一个和最后一个的广告信息去掉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. 总结

​ 本次实战主要目的还是帮助大家熟悉bs4这个库的使用技巧,实战只是顺带的,懂得如何运行这个工具比懂得如何爬取一个网站更加重要。

​ 除此之外,不难看出,lxml库更像一个从上到下的定位模式,你想要获取某一个标签,首先需要考虑其上某个更加具体的标签;而bs4则更直接,如果你要获取的标签比较特别,可以直接定位它,而无需通过其他关系来确定

​ 下一篇,开始讲解如何解决动态网页,即selenium库。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux中shell脚本——for、while循环及脚本练习

目录 一.for循环 1.1.基本格式 1.2.类C语言格式 二.while循环 2.1.基本格式 2.2.死循环语句 三.跳出循环 3.1.continue跳出循环 3.2.break跳出循环 四.常用循环 4.1.循环打印九九乘法表 4.2.循环ping测试某个网段网络连通性 4.3.while死循环实现猜数字游戏 4.4.数…

Linux的热拔插UDEV机制

文章目录 UDEV简介守护进程基本特点 守护进程和后台进程的区别开发守护进程结束 UDEV简介 udev是一个设备管理工具,udev以守护进程的形式运行,通过侦听内核发出来的uevent来管理/dev目录下的设备文件。 udev在用户空间运行,而不在内核空间 …

硬编码基础一(经典定长指令,寄存器相关)

硬编码基础一(定长指令) push/pop 通用寄存器 50~57是push8个32位通用寄存器 58~5f是pop8个32位通用寄存器 inc/dec 通用寄存器 40~47是inc8个32位通用寄存器 47~4f是dec8个32位通用寄存器 八位通用寄存器的立即数赋值 b0~b3 {立即数} 是低八位(…

MAC访问MySQL下的data目录

1.查看创建表存储路径 show variables like datadir 2.快捷键comshiftG,输入查询到的地址 3.终端输入 sudo chmod -R arwx /usr/local/mysql/data 然后输入密码即可

第五十七天

HTML5 ●Web 存储 Web 存储需要更加的安全与快速. 这些数据不会被保存在服务器上,但是这些数据只用于用户请求网站数据上.它也可以存储大量的数据,而不影响网站的性能。 •客户端存储数据的两个对象为: localStorage 用于长久保存整个…

【使用Zookeeper当作注册中心】自己定制负载均衡常见策略

自己定制负载均衡常见策略 一、前言随机(Random)策略的实现轮询(Round Robin)策略的实现哈希(Hash)策略 一、前言 大伙肯定知道,在分布式开发中,目前使用较多的注册中心有以下几个&…

Typescript基础知识(类型拓宽、类型缩小)

系列文章目录 引入一:Typescript基础引入(基础类型、元组、枚举) 引入二:Typescript面向对象引入(接口、类、多态、重写、抽象类、访问修饰符) 第一章:Typescript基础知识(Typescri…

1.vue3+vite开发中axios使用及跨域问题解决

一、跨域问题解决 1.基于vitevue3配置时,在vite.congig.js文件server项目中添加 proxy代理 文件名:vite.congig.js server: {open: true,//启动项目自动弹出浏览器port: 3000,proxy: {/api: {target: http://localhost:8000/api/,changeOrigin: true,rew…

elementPlus——图标引入+批量注册全局组件——基础积累

因为我们要根据路由配置对应的图标,也要为了后续方便更改。因此我们将所有的图标注册为全局组件。(使用之前将分页器以及矢量图注册全局组件的自定义插件)(所有图标全局注册的方法element-plus文档中已给出) 全局注册…

Docker-compose详解和LNMP搭建实战

目录 一、Docker-compose简介 1.前言 2.概述 二、Docker-compose安装 安装源获取 安装包下载 三、YAML文件格式及编写注意事项 1.简介 2.使用方法 四、Docker Compose 常用命令 五、Docker Compose 配置常用字段 六、Docker-compose搭建LNMP实战 一、Docker-compose…

MySQL的安装以及卸载

下载官网 https://www.mysql.com/ 切到下载tab页 找到 MySQL Community Server 或者 MySQL Community (GPL) Downloads --> MySQL Community Server 点击download按钮: 点击download进入下载页面选择No thanks, just start my download就可以开始下载了。 下…

【ARM】Day5 uart总线, LED点亮实验(C语言实现)

1. 思维导图 2. LED点灯实验(C语言实现) gpio.h #ifndef _LED_H__ //防止头文件重复包含_ #define _LED_H__//RCC_MP_AHB4ENSETR寄存器封装 #define RCC_MP_AHB4ENSETR (*(volatile unsigned int*)0x50000A28)//GPIO使用封装结构体 typedef struct{v…

【Linux】进程优先级

一、基本概念 Hello,大家好。本文我们要来介绍的是有关Linux下【进程优先级】,首先我们要了解的是其基本概念 在 Linux基础篇之权限 一文中我们有谈到过什么是权限,在Linux下有权限和无权限的区别在哪里。那现在的话我们就要来对比一下【权限…

js 的正则表达式(二)

1.正则表达式分类: 正则表达式分为普通字符和元字符。 普通字符: 仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。也就是说普通字符只能够匹配字符串中与它们相同的字符。 元字符: 是一些具有特殊含…

快速连接服务器脚本 可从多个服务中选择并连接

使用 python 做一个可选择服务器登录连接的脚本 前置条件 需要有python 环境python --version 显示版本号即可检查 python 是否有 paramiko 包没有的话 python install paramiko创建一个python 文件,内容如下 # -*- coding: utf-8 -*-""" Authors: huxiaohua…

一文科普,配资门户网是什么?

配资门户网是一个为投资者提供配资服务的平台。配资是指通过借用他人资金进行投资交易的一种金融操作方式。配资门户网作为一个线上平台,为投资者提供了方便、快捷的配资服务。 配资门户网提供了多种不同的配资方案,以满足不同投资者的需求。投资者可以…

神经网络基础-神经网络补充概念-42-梯度检验

概念 梯度检验(Gradient Checking)是一种验证数值计算梯度与解析计算梯度之间是否一致的技术,通常用于确保实现的反向传播算法正确性。在深度学习中,通过梯度检验可以帮助验证你的神经网络模型是否正确地计算了梯度,从…

LVS及负载均衡群集的搭建

一、群集简介 群集是为解决某个特定问题将多台计算机组合起来形成的单个系统,由多台主机构成,但对外只表现为一个整体,相当于一台大型计算机提供服务。 互联网应用中,随着站点对硬件性能、响应速度、服务稳定性、数据可靠性等要求…

适配器模式:让不兼容的接口协同工作

在面向对象设计中,适配器模式是一种常见的结构型设计模式。它允许将不兼容的接口转换成客户端所期望的另一个接口,从而使不同的类协同工作。适配器模式的主要目的是解决不同接口之间的兼容性问题,同时也提高了代码的可重用性和灵活性。 问题…

通过Git使用GitHub

目录 一、建立个人仓库 二、配置SSH密钥 三、克隆仓库代码 四、推送代码到个人仓库 五、代码拉取 一、建立个人仓库 1.建立GitHub个人仓库,首先注册GitHub用户。注册好了之后,打开用户的界面 然后就是配置问题 配置好后拉到最下方点击create repos…