关于python爬虫解析的问题

news/2024/10/21 7:32:08/

在进行Python爬虫解析时,需要注意以下事项:

1、良好的网站使用协议:需要遵守网站的robots.txt文件,以确保你的爬虫程序不会将网站拦截下来。

2、编码问题:需要正确设置HTTP头和解析器的编码,以确保爬虫程序能够正确地解析网站的信息。

3、数据解析:需要适当地处理HTML文档中的标签,以便从中筛选出目标数据。

4、网站反爬虫机制:需要了解网站的反爬虫机制,采取相应的策略,确保爬虫程序不会被网站屏蔽。

5、频率控制:需要适度控制爬虫程序的请求频率,以避免给网站带来过多负荷。

6、数据存储:需要将爬取到的数据存储到合适的位置,例如数据库或文件系统中。

7、长期稳定性:需要优化代码,确保程序长期稳定地工作。

今天主要整理python的三种解析方法

正则表达式

1、正则解析主要是以//.和//.?的两种从而获得想要获取的数据就比如说在分页爬取的时候中间的

ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
img_src_list = re.findall(ex, page_text, re.S)

这是一个正则表达式的一个解析式 中间的(.*?)就是用来匹配你所要的内容。

主要就是是用python所提供的re模块用于实现正则表达式的操作,在操作的时候可以使用re提供的方法(search(),match(),findall())进行字符串处理;

他们三个都有共同的参数

pattern:模式字符串

string:要进行匹配的字符串

flags:可选参数,表示标识位,用于控制匹配方式,如是否匹配字母大小写

在这里插入图片描述

match()

用于从字符串的开始位置进行匹配如果开始位置匹配成功择返回match对象,否则择返回None

search()

用于整个字符串中搜索第一个匹配到的值,如果匹配成功则返回search对象,如果没有匹配成功则返回None

findall()

用于匹配整个列表中所有符合正测表达式的字符串并一列表的形式返回,,没有则返回None

关于.和.?的区别

.表示匹配换行符之外的任何单字符,*表示零次或者多次,所以.和在一起就是表示出现任意字符零次或者多次。如果没有?则表示贪婪模式

比如 a.b他将会匹配最长的以a开始,以b结束的字符串

.?表示懒惰模式

比如a.?b将会匹配以a开始,以b结束匹配最短的且符合标准的字符串

# 分页爬取
import requests
import os
import reif __name__ == '__main__':if not os.path.exists('./fenyelibs'):os.mkdir('./fenyelibs')else:print()# 设置一个通用的url模版url = 'https://www.qiushibaike.com/imgrank/page/%d/'# pagenum=2headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.51'}for item in range(1, 3):pagenum = itemnew_url = format(url % pagenum)# print(new_url)page_text = requests.get(url=new_url, headers=headers).textex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'img_src_list = re.findall(ex, page_text, re.S)for src in img_src_list:new_src = 'https:' + srcimg_data = requests.get(new_src, headers=headers).contentimg_name = src.split('/')[-1]img_path = './fenyelibs/' + img_namewith open(img_path, "wb")as file:file.write(img_data)print(img_name, '下载完成')print('下载完成!!!')

bs4解析

# 针对与bs4  实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
#            通过调用BeautifulSoup对象中相关的属性或者办法进行标签定位
from bs4 import BeautifulSoupif __name__ == '__main__':fp = open('./text.html', 'r', encoding='utf-8')soup = BeautifulSoup(fp, 'lxml')#print(soup)print(soup.a)#soup.tagname 返回的是HTML中第一次出现的tagname对应的标签print('-----')print(soup.div)#soup.find()print('------')print(soup.find('div'))#相当于soup.div#属性定位print('---------属性定位:\n',soup.find('div',class_='song'),'\n')print('--------find_all:',soup.find_all('a'))#selectprint('----select\n',soup.select('.tang'),'\n')#某种选择器(id,class,标签...选择器),返回的是一个列表 只要符合选择器的要求#层级选择器print(soup.select('.tang > ul > li > a')[0],'\n')#>是一个层级print(soup.select('.tang > ul a')[0])#空格表示多个层级#获取标签之间的文本数据  text 和get_text()可以获取标签中的所有文本内容#                     string只可以获取该标签下面的直系文本内容print(soup.select('.tang > ul a')[0].get_text())print(soup.select('.tang > ul a')[0].text)print(soup.select('.tang > ul a')[0].string,'\n')print('测试一下','\n')print(soup.find('div',class_='song').text)#获取标签中的属性值'print('获取标签中的属性值:\n',soup.select('.tang>ul a')[0]['href'])

他这中间会有find find_all select 三种查找的犯法

find是返回查找到的第一个值

find_all是返回查找到的所有值以列表形式返回

select 某种选择器(id,class,标签…选择器),返回的是一个列表 只要符合选择器的要求

他在进行网页查找的时候要记得在他div的标签属性下加.使用>进行下一个选项如果要跨级去中的话那就要是用空格

xpath解析

from lxml import etree
import requestsif __name__ == '__main__':print('hello python!!')#实例化一个etree对象,并且被解析的源码也加载到了该对象中tree=etree.parse('text.html')#调用xpathr=tree.xpath('/html/body/div/text()')#在HTML前边加一个/标识从根节点开始 后边的/标识一个层级# r=tree.xpath('/html//div')#//表示多个层级#r=tree.xpath('//div')#//标识可以从任意的位置去定位div标签print(r)# r1 = tree.xpath('//div[@class="sng"]/p[3]')# r2 = tree.xpath('//div[@class="sang"]/p[3]')  # 索引是从1开始的# # print(r1)# print(r2)r3=tree.xpath('//div[@class="tang"]//li[5]/a/text()')[0]#取文本用/text()print(r3)r4=tree.xpath('//li[7]//text()')[0]#/txet()获取的是标签中直系的文本内容#//text()获取的是标签中的非直系的内容print(r4)r5=tree.xpath('//li//text()')for item in r5:print(item)print('----------------')r6=tree.xpath('//div[@class="sang"]/img/@src')#取属性值用/@sttrName 可以取到标签属性当中的文本内容print(r6)

这个他就使用的是/进行分级的 要是要想跨级进行查找的话那就要使用//


http://www.ppmy.cn/news/51723.html

相关文章

DAY05_面向对象基础

面向对象并不是一个技术&#xff0c;而是一种指导思想。 为什么要用面向对象编程&#xff1f; 因为生活中&#xff0c;我们解决问题时&#xff0c;就是采用这种指导思想去解决的。所以&#xff0c;我们写程序去解决问题时&#xff0c;如果也能采用这种指导思想就会使得程序变…

OpenGL光照:颜色

知识点归纳 现实世界中有无数种颜色&#xff0c;每一个物体都有它们自己的颜色。我们要做的工作是使用(有限的)数字来模拟真实世界中(无限)的颜色&#xff0c;因此并不是所有的现实世界中的颜色都可以用数字来表示。然而我们依然可以用数字来代表许多种颜色&#xff0c;并且你甚…

Linux中vim常用命令

记录下来&#xff0c;下次忘了好找。 一些常用命令 保存退出 :wq 不保存退出 :q 不保存强制退出 :q! esc进入普通模式 用Vim写一个文件&#xff0c;写完保存退出的流程 1.编辑文件&#xff0c;若文件已存在&#xff0c;则存放于原文件&#xff1b;若文件不存在&…

20230422 | 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142. 环形链表 II

1、24. 两两交换链表中的节点 初始时&#xff0c;cur指向虚拟头结点&#xff0c;然后进行如下三步&#xff1a; 操作之后&#xff0c;链表如下&#xff1a; 看这个可能就更直观一些了&#xff1a; /*** Definition for singly-linked list.* public class ListNode {* i…

【MyBatis基础】SpringBoot集成MyBatisPlus的基于字段隔离的多租户实现

文章目录 1. 多租户在数据存储上的实现方式2. 基于字段的隔离方式实践3. 补充 摘要&#xff1a;多租户的含义是让多用户共用相同的系统或组件&#xff0c;但是又能保证各个用户之间数据是隔离的。多租户技术可以实现多个租户共用系统实例&#xff0c;而且同时能实现系统实例的个…

Bean作用域和生命周期

修改的Bean案例 User&#xff1a; package com.bean;import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Controller;public class User {private int id;private String name;Overridepublic String toString() {return "Use…

Tomcat 配置与部署

http 协议就是 http 客户端和 http 服务器之间通信的协议 , 而Tomcat 就是 java 圈子中最广泛使用的 http 服务器. 下载Tomcat Tomcat官网 Tomcat 的版本 , 和后续的 servlet 版本是强相关的 , 此处使用 tomcat 8 , 对应的 servlet 就是 3.1 下载一个 zip 压缩包解压缩即可 T…

什么蓝牙耳机适合学生党?学生党蓝牙耳机性价比排行

现如今&#xff0c;市场上有各种各样的品牌和蓝牙耳机&#xff0c;让人在选择时不免眼花缭乱。作为学生党&#xff0c;在选择一样东西的时候&#xff0c;性价比无疑会成为其选择的重要参考因素。下面&#xff0c;我来给大家分享几款适合学生党的高性价比蓝牙耳机&#xff0c;一…