python爬虫学习记录

news/2024/7/19 10:42:46 标签: python, 爬虫, 学习

初识爬虫

爬虫的概念

「什么是爬虫

爬虫:通过编写程序,模拟浏览器上网,并抓取有价值的数据的过程

爬虫:门户网站通过制定相应的策略或技术手段,来阻止爬虫程序对其网站数据的爬取

反反爬爬虫程序可以采用一些技术手段,来绕过或破坏门户网站的反爬机制,从而爬取到有用的数据

爬虫与反爬虫就是一对矛与盾

爬虫合法性探究」

爬虫可能带来的风险?

  • 爬虫干扰了被访问网站的正常运营

  • 爬虫抓取了受到法律保护的特定类型的数据或信息

如何合理地使用爬虫

  • 爬虫程序进行优化,避免干扰网站的正常运行

  • 不要爬取涉及商业机密等敏感信息

爬虫的君子协议」

通常,网站的robots.txt文件中声明了那些数据可以被爬取,那些数据不可以被爬取(非强制性)

爬虫的分类

在不同的使用场景下,爬虫的分类有

  1. 通用爬虫:抓取一整张页面的数据(很可能包含大量无用信息)

  2. 聚焦爬虫:抓取页面中特定的局部内容,必须建立在通用爬虫的基础之上

  3. 增量爬虫:只会爬取网站中最新更新的数据

网络请求与响应

http协议

http(s)协议是服务器和客户端进行数据交互的一种形式,服务器和客户端都需要遵守该协议才能进行数据交互

https协议是http协议的升级版,服务器与客户端的数据交互是通过证书加密的,攻击者很难获得有价值的信息

「常用的请求头信息」

Request Header描述
User-Agent请求载体的身份标识
Connection请求完毕后,保持连接还是断开连接

「常用的响应头信息」

Response Header描述
Content-Type服务器响应数据的类型

requests模块

requestspython中的一个基于网络请求的模块,用来模拟浏览器发送请求。

「requests模块的安装与使用」

python">pip install requests   

import requests      
url = 'http://www.baidu.com'   
resp = requests.get(url)    #发起一个get请求,并获得响应数据   
page_content = resp.text   
print(page_content)   
属性描述
resp.text以字符串形式返回,通常是页面的html源代码
resp.content以二进制形式返回,比如一张图片、一个音频
resp.json()返回一个字典对象(当响应数据是json类型时使用)

「基于requests的简易网页采集器(使用到了UA伪装)」

python">import requests      

# 1. 准备数据   
url = 'https://www.sogou.com/web'   
word = input('Enter a word:')   
params = {  #请求参数,拼接在url后      
 'query': word   }   
headers = { #请求头,伪装成浏览器      
 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'   }    
   
 # 2. 发起请求   
 resp = requests.get(url,params,headers=headers)   
 resp.encoding = resp.apparent_encoding   
 page_content = resp.text   
 print(page_content)     
  
 # 3. 持久化存储   
 file_name = word + '.html'   
 with open(file_name,'w',encoding='utf-8') as fp:       
     fp.write(page_content)   
 print(file_name,'保存成功!')   

数据解析

数据解析是在得到整个网页源代码后,对其中的有用信息进行提取的过程。属于聚焦爬虫

「数据解析的一般步骤」

检查网页源代码发现,有价值的数据一般存放在标签中,或者标签的属性中。所以数据解析的一般步骤是:1.获取网页源代码 2.标签定位 3.解析数据

F12检查元素中的数据不一定在页面源代码中,也有可能是通过ajax动态刷新的数据,这是我们在数据解析时需要注意的。数据解析要以页面源代码为准!

「Python中数据解析的三种方式」

1.正则表达式(通用) 2.BeautifulSoup4(python独有) 3.xpath(推荐,通用性最强)

使用正则表达式

建议先把要提取的那部分源码单独复制,对照着去写正则表达式(F12太乱了🤣)

从重复的标签(如li)开始写正则,那么这个正则可以提取到多组数据哦

「re.findall(pattern,string,flags)」

参数描述
pattern匹配的正则表达式
string待匹配的文本字符串
flags标志位。用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
标志位描述
re.S使.能够匹配包括换行在内的所有字符
re.M多行匹配,影响^和$
re.I使匹配对大小写不敏感
正则表达式描述
.匹配除换行符外的任意单个字符
*匹配多个字符
?非贪婪匹配

使用BeautifulSoup

对于一个网页来说,都有一定的特殊结构和层级关系,而且很多节点都用id和class来区分。所以可以借助网页的结构和属性来提取数据。

「使用BeautifulSoup的一般步骤」

  1. 实例化一个BeautifulSoup对象,并且将页面源代码加载到该对象中

  2. 调用BeautifulSoup对象提供的属性或方法进行标签定位和数据提取

「BeautifulSoup4的安装与使用(需要一并下载lxml解析器)」

python">pip install bs4   
pip install lxml   

from bs4 import BeautifulSoup   
import requests  
    
# 加载html有两种方式  
# 方式一 使用本地html文档中的数据   
fp = open('./猫羽雫.html','r',encoding='utf-8')   
soup = BeautifulSoup(fp,'lxml')   
print(soup) 
#我们发现,soup对象的内容就是加载到该对象中的html源码   
   
# 方式二 从互联网上获取html源码   
url = 'https://www.baidu.com'   
resp = requests.get(url)   
resp.encoding = resp.apparent_encoding   
soup = BeautifulSoup(resp.text,'lxml')   
print(soup)   

「BeautifulSoup对象中提供的属性和方法」

  1. 根据标签名或选择器定位,返回标签之间的所有内容
方法描述
find(tag,attr=value)根据标签名和属性进行定位,只返回符合条件的第一个元素内容
find_all(tag,attr=value)返回一个列表,用法同上
select(css选择器)使用CSS选择器进行定位,返回一个列表

2. 获取标签之间的文本数据(不包括子标签)

属性描述
.text获取所有文本内容
.string只能获取直系的文本内容

3. 获取标签中指定属性的值

属性描述
[attr]获取属性对应的属性值

使用xpath解析

xpath解析是最常用、最便捷、最高效,且通用性最强的解析方式。xpath是根据元素所处层级进行定位的

「xpath解析的一般步骤」

  1. 实例化一个etree对象,并将要解析的html页面源码数据加载到对象中

  2. 调用etree对象的xpath(xpath表达式)方法结合xpath表达式实现标签的定位和数据提取

「xpath的安装与使用」

python">pip install lxml   

from lxml import etree   
import requests      
# 加载html有两种方式   
# 方式一 使用本地html文档中的数据   
etree.parse('./猫羽雫.html')      

# 方式二 从互联网上获取html源码   
url = 'https://www.baidu.com'   
resp = requests.get(url)   
resp.encoding = resp.apparent_encoding   
etree.HTML(page_content)   
方法描述
etree.HTML(html)实例化一个etree对象,并加载要解析的html
etree.parse(filepath)实例化一个etree对象,并加载要解析的html(本地html)
xpath(xpath表达式)使用xpath表达式进行标签定位,返回一个列表

xpath()方法返回一个列表,如果xpath表达式只进行了定位,没有进行数据提取,那么列表中每个元素都将是一个Element对象。

「xpath表达式用法」

  1. 根据html元素层级进行定位
xpath表达式描述
/表示单个层级,放在开头表示html根元素
//表示多个层级(常用)
./表示当前标签
[@attr=value]根据属性进行定位
[index]根据元素所处位置进行定位,index从1开始
  1. 提取标签之间的文本数据
xpath表达式描述
/text()获取标签中的文本,返回一个列表
//text()可以获取标签中非直系的文本,返回一个列表
  1. 提取标签中指定属性的值
xpath表达式描述
/@attr获取标签中属性对应的值

数据解析实战

我们将通过一个案例具体说明

Wallhaven网站

需求:获取给定链接下的图片并下载保存到本地

python">import requests
import time
from bs4 import BeautifulSoup

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36'
}
out_path = 'D:\\wallhaven'   # 下载图片保存目录,可自定义

start = 1   # 给定爬取起始页

def get_img():
    api_url = f'https://wallhaven.cc/toplist?page={start}'
    data = requests.get(api_url)
    data = data.text
    
    # 解析数据
    soup = BeautifulSoup(data, "html.parser")
    item_list = soup.find_all("a", class_='preview')  
    # 通过F12分析图片位置,找到a标签并且class为'preview'的数据

    for lst in item_list:
        url = lst.get('href')  # 从数据列表中获取属性href值  类似https://wallhaven.cc/w/we5ov6
        # 继续从上个url中获取图片数据并解析
        data1 = requests.get(url).text
        soup = BeautifulSoup(data1, "html.parser")

        its = soup.find_all('img', id='wallpaper')  # 获取源图片地址,大图,即为所需图片
        for wall in its:
            url2 = wall.get('src')
            res = requests.get(url=url2, headers=headers).content
            name = url2.split('/')[-1]
            img_save_path = out_path + '\\' + name
            with open(img_save_path, 'wb') as f:  # 存储图片
                f.write(res)  # 写入图片
                print(name + '    >>>>>>>>>>>>>>>>>>>>  下载完成')
                f.close()
                
# 循环下载主入口,粗略
while 1:
    get_img()
    time.sleep(5) 
    start += 1
	
	# 可自定义循环退出条件
    if start > 500:
        break



写在后面,爬取了一些二次元图如下:
在这里插入图片描述
看多了也就那样~~~


http://www.niftyadmin.cn/n/64990.html

相关文章

解决rimraf使用时提示unexpected token “.”

解决rimraf使用时提示unexpected token “.” 前言 最近运行一个Cordova项目时,npm install后打包,命令栏提示了下面这个问题: 很奇怪啊,就我这里有问题,别人之前都没事,很头疼。 问题原因 经过一番摸索…

【操作系统】磁盘IO常见性能指标和分析工具实战

1.磁盘读写常见的指标 (1)IOPS(Input/Output Operations per Second) 指每秒能处理的I/O个数,表示块存储处理读写(输出/输入)的能力,单位为次,有顺序IOPS和随机IOPS比如…

[Web] 简单瀑布流布局实现

目前的纯 CSS 布局, 是没办法实现比较完美的瀑布流布局的. 参考: CSS总结:瀑布流布局 - 黑白程序员 我使用 JS CSS, 并且自动布局实现了较为简单, 观赏性好的瀑布流布局. 代码 HTML: <!DOCTYPE html> <html lang"en"> <head><link rel&quo…

多边形网格算法笔记

本文是处理多边形和网格的各种笔记和算法。 推荐&#xff1a;使用 NSDT场景设计器 快速搭建 3D场景。 1、表面简化 下面描述了一种方法&#xff0c;用于减少构成表面表示的多边形数量&#xff0c;同时仍试图保留表面的基本形式。 如果正在为渲染和/或交互环境寻求性能改进&…

greenDao的使用文档

介绍&#xff1a;greenDAO 是一款轻量级的 Android ORM 框架&#xff0c;将 Java 对象映射到 SQLite 数据库中&#xff0c;我们操作数据库的时候&#xff0c;不在需要编写复杂的 SQL语句&#xff0c; 在性能方面&#xff0c;greenDAO 针对 Android 进行了高度优化&#xff0c; …

SD卡里的视频无法正常播放出来怎么办?

在日常工作和学习中经常会用到SD卡这个存储设备&#xff0c;它存储空间大&#xff0c;使用方便&#xff0c;很多设备上都使用SD卡作为存储工具。SD卡已经成为我们众多电子设备中重要的一员&#xff0c;为我们存储着相片、视频、文档、音频等数据。 SD卡为我们提供了巨大便利&a…

【开源项目】一款私有化部署的知识管理工具,你值得拥有!

一、知识获取与沉淀企业发展到一定阶段&#xff0c;必须重视知识管理&#xff0c;以提升组织和个人对知识的重视程度和利用效率。知识管理的作用是将所需知识归集整理&#xff0c;但于查找利用&#xff1b;让知识成为企业发展的能动力,减缓由人员的变化而给企业带来的不必要损失…

Linux进阶(Shell编程学习一)

由于shell脚本在java项目运维方面极其重要&#xff0c;比如服务的启动脚本&#xff0c;日志的分割脚本&#xff0c;文件的管理脚本大多都是shell脚本去实现的。所以作为java开发者懂linux的基本命令&#xff0c;会基本的shell编程是必要的。 Shell 是一个用 C 语言编写的程序&…