python渗透工具编写学习笔记:10、网络爬虫基础/多功能编写

目录

前言

10.1 概念

10.2 调度器/解析器

10.3 存储器/去重器

10.4 日志模块

10.5 反爬模块

10.6 代理模块


 前言

    在渗透工具中,网络爬虫有着不可忽视的作用,它能够快速而精准的搜寻、提取我们所需要的信息并按照我们所需要的格式排列,那么今天我们就来学习使用python编写实用的爬虫吧!坚持科技向善,勿跨越法律界限,代码仅供教学目的。初出茅庐,如有错误望各位不吝赐教。

10.1 概念

    网络爬虫是指自动访问互联网上的网页并提取相关信息的程序。Python是一种常用的编程语言,可以用来编写网络爬虫。Python爬虫的架构通常包括以下几个组件:

  1. 调度器(Scheduler):负责管理爬取的URL队列,将待爬取的URL添加到队列中,并根据一定的策略从队列中取出URL进行爬取。

  2. 下载器(Downloader):负责下载URL对应的网页内容,并将下载结果返回给爬虫程序。

  3. 解析器(Parser):负责解析下载下来的网页内容,提取出需要的数据。

  4. 存储器(Storage):负责将解析出的数据进行存储,可以是保存到数据库中、写入文件等。

  5. 去重器(Deduplicator):负责对已下载的URL进行去重,避免重复的爬取。

  6. 调度器、下载器、解析器、存储器之间一般通过消息队列、数据库等通信机制进行交互。

在实际的爬虫项目中,爬虫的整体流程为:调度器从URL队列中取出一个URL,交给下载器下载该URL对应的网页内容,下载完成后将结果交给解析器进行解析,提取出需要的数据,并交给存储器进行存储。同时,去重器会对已下载的URL进行去重,避免重复爬取。

10.2 调度器/解析器

   网络爬虫是指自动访问互联网上的网页并提取相关信息的程序。Python是一种常用的编程语言,也可以用来编写网络爬虫。

我们用Python编写一个简单的爬虫调度器:

在Python中,你可以使用requests库来发送HTTP请求获取网页内容,使用BeautifulSoup库来解析网页内容。

import requests
from bs4 import BeautifulSoup

发送请求获取网页内容:使用requests库发送HTTP请求并获取网页内容。

url = "https://www.example.com"  # 要爬取的网页地址
response = requests.get(url)
html = response.text  # 获取网页内容

要学习如何编写爬虫的解析器,我们需要先学习正则表达式的编写: 

正则表达式是一种用来匹配字符串的工具,可以用来搜索、替换和提取字符串中的特定模式。在Python中,正则表达式的相关函数和模块被封装在re模块中。

下面我们再来学习编写爬虫的解析器,用于筛选出我们需要的信息。我们可以使用re模块来进行字符串的正则表达式匹配。下面是一些常用的re模块函数:

  1. re.match(pattern, string, flags=0):

    • 函数用于尝试从字符串的起始位置匹配一个模式。
    • 如果匹配成功,返回一个匹配对象;如果匹配失败,返回None。
    • pattern:要匹配的正则表达式模式。
    • string:要匹配的字符串。
    • flags:可选参数,用于控制匹配的模式。
  2. re.search(pattern, string, flags=0):

    • 函数用以在字符串中搜索匹配的第一个位置,返回一个匹配对象。
    • pattern:要匹配的正则表达式模式。
    • string:要匹配的字符串。
    • flags:可选参数,用于控制匹配的模式。
  3. re.findall(pattern, string, flags=0):

    • 函数用以在字符串中搜索匹配的所有位置,返回一个列表。
    • pattern:要匹配的正则表达式模式。
    • string:要匹配的字符串。
    • flags:可选参数,用于控制匹配的模式。

下面是一个示例,演示如何使用re模块来匹配字符串:

import re# 匹配字符串中的数字
pattern = r'\d+'
string = 'abc123def456ghi'# 使用re.search()匹配第一个数字
match = re.search(pattern, string)
if match:print(f'Matched: {match.group()}')  # 输出:Matched: 123# 使用re.findall()匹配所有数字
matches = re.findall(pattern, string)
if matches:print(f'All Matches: {matches}')  # 输出:All Matches: ['123', '456']

在上面的示例中,使用正则表达式模式r'\d+'匹配字符串中的数字。首先使用re.search()函数匹配第一个数字,然后使用re.findall()函数匹配所有数字。输出结果显示匹配到的数字。


学会了re模块的主要函数,接下来我们来学习正则表达式筛选条件的编写: 

  1. 字符匹配

    • 字符:使用普通字符直接匹配,例如匹配字符串 "hello",可以使用正则表达式 "hello"。
    • 句点(.):匹配任意一个字符,除了换行符(\n)。
    • 字符集([]):匹配方括号中的任意一个字符。例如,[aeiou] 匹配任意一个元音字母。
    • 转义字符(\):用来匹配特殊字符。例如,匹配圆括号字符,可以使用 "("。
    • 重复次数:用于指定一个字符的重复次数。例如,a{3} 匹配 "aaa"。
    • 元字符(\d、\w、\s):用于匹配特定类型的字符。例如,\d 匹配任意一个数字字符。
  2. 边界匹配

    • 开始位置(^):匹配字符串的开始位置。
    • 结束位置($):匹配字符串的结束位置。
  3. 重复匹配

    • 重复(*):匹配前面的元素0次或多次。
    • 加号(+):匹配前面的元素1次或多次。
    • 问号(?):匹配前面的元素0次或1次。
    • 花括号({}):匹配前面的元素指定的次数范围。例如,a{2,4} 匹配 "aa"、"aaa"、"aaaa"。
  4. 分组和捕获

    • 圆括号(()):用于分组的目的。例如,(ab)+ 匹配 "ab"、"abab"、"ababab"。
    • 捕获组(\1、\2、\3...):用于引用分组中的内容。例如,(\w+)\s+\1 匹配 "hello hello"。
  5. 特殊序列

    • \d:匹配任意一个数字字符。等价于 [0-9]。
    • \D:匹配任意一个非数字字符。等价于 [^0-9]。
    • \w:匹配任意一个字母、数字或下划线字符。等价于 [a-zA-Z0-9_]。
    • \W:匹配任意一个非字母、数字或下划线字符。等价于 [^a-zA-Z0-9_]。
    • \s:匹配任意一个空白字符,包括空格、制表符、换行符等。
    • \S:匹配任意一个非空白字符。

以上是正则表达式的一些常用语法,我们再来看看爬虫常用的筛选条件:

soup = BeautifulSoup(html, "html.parser")  # 使用html.parser解析器解析网页内容
# 提取需要的信息
title = soup.title.text  # 提取网页标题
links = soup.find_all("a")  # 提取所有链接

10.3 存储器/去重器

    完成了调度器与解析器的编写,我们再来看三要素里的最后一个:爬虫的存储器。它用于将爬取完成后的数据储存起来,下面我们利用python的文件写入方法来对数据进行储存,并将提取的信息保存到文件或数据库中。

# 保存到文件
with open("output.txt", "w") as f:f.write(title)for link in links:f.write(link.get("href"))

好了!我们已经写出了网络爬虫最主要的三个部分,接下来是时候为它添加上更加丰富的功能了,为了使我们的爬虫不会爬取相同的网页,我们来编写一个爬虫的去重器。以下是爬虫去重器的示例代码:

import hashlibdef get_md5(url):"""计算URL的MD5值"""if isinstance(url, str):url = url.encode("utf-8")m = hashlib.md5()m.update(url)return m.hexdigest()class Deduplicator:def __init__(self):self.visited_urls = set()def is_visited(self, url):"""判断URL是否已经被访问过"""url_md5 = get_md5(url)if url_md5 in self.visited_urls:return Trueelse:self.visited_urls.add(url_md5)return False

使用方法:

deduplicator = Deduplicator()
url = "http://example.com"if deduplicator.is_visited(url):print("URL已被访问过")
else:print("URL未被访问过")

以上代码中,get_md5函数用于计算URL的MD5值,将其作为唯一的标识。Deduplicator类用于存储已经访问过的URL,通过调用is_visited方法判断URL是否已经被访问过。如果URL已被访问过,则返回True;如果URL未被访问过,则将其MD5值添加到已访问集合中,并返回False。

10.4 日志模块

    日志模块,可以使我们的爬虫爬取日志信息,提取不同级别的日志,编写Python爬虫的日志模块可以使用Python内置的logging模块来实现。下面是一个简单示例:

import logging# 创建日志对象
logger = logging.getLogger('crawler')
logger.setLevel(logging.DEBUG)# 创建文件handler,用于将日志写入文件
file_handler = logging.FileHandler('crawler.log')
file_handler.setLevel(logging.DEBUG)# 创建控制台handler,用于在控制台输出日志
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)# 定义日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)# 将handler添加到日志对象中
logger.addHandler(file_handler)
logger.addHandler(console_handler)

以上代码创建了一个名为'crawler'的日志对象,并设置了日志级别为DEBUG,即最低级别的日志会输出到文件和控制台。可以根据需求进行调整日志级别。

接下来,可以在爬虫代码中使用日志对象来记录日志信息。例如:

url = 'http://example.com'try:# 爬取数据的代码logger.debug(f'Start crawling url: {url}')# ...# 爬取成功的日志信息logger.info(f'Successfully crawled url: {url}')
except Exception as e:# 爬取失败的日志信息logger.error(f'Failed to crawl url: {url}. Error message: {str(e)}')

以上代码会在开始爬取URL和成功爬取URL时分别记录DEBUG级别和INFO级别的日志信息,如果爬取过程中出现异常,则会记录ERROR级别的日志信息,并将异常信息作为日志消息的一部分。所有日志信息会同时输出到文件和控制台。

这样,就完成了一个简单的Python爬虫日志模块的编写。我们可以根据实际需求对日志模块进行扩展和优化,例如添加日志文件的切割、设置日志文件大小等。

10.5 反爬模块

    当遇到反爬机制时,我们可以使用Python编写一些反爬模块来应对。这些模块可以帮助我们绕过一些常见的反爬手段,如User-Agent检测、验证码识别、IP封锁等。

以下是一个示例,演示了如何使用Python的requests库和验证码识别库tesseract来实现一个简单的反爬模块:

import requests
from PIL import Image
import pytesseract# 请求头,可以根据具体的网站进行调整
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}# 请求网页,可以添加其他参数,如代理IP等
response = requests.get('http://example.com', headers=headers)# 如果返回的响应中有验证码图片,可以使用Pillow库来处理
if 'captcha' in response.text:# 找到验证码图片的URLcaptcha_url = 'http://example.com/captcha.jpg'captcha_response = requests.get(captcha_url, headers=headers)# 保存验证码图片到本地with open('captcha.jpg', 'wb') as f:f.write(captcha_response.content)# 使用tesseract来识别验证码captcha = pytesseract.image_to_string(Image.open('captcha.jpg'))# 构建包含验证码的表单数据data = {'captcha': captcha,# 其他表单数据...}# 提交包含验证码的表单数据response = requests.post('http://example.com/submit', data=data, headers=headers)# 处理响应内容
# ...

注:这只是一个简单的示例,实际应用时可能需要根据具体的反爬机制进行具体调整和优化。此外,还可以考虑使用代理IP池、使用多个账号轮流访问等更复杂的反爬策略。

10.6 代理模块

最后,我们再来使用Python编写爬虫的代理模块:

import requests# 使用代理IP访问网页
def request_with_proxy(url, proxies):try:# 使用get方法发送请求response = requests.get(url, proxies=proxies)# 返回响应内容return response.textexcept requests.exceptions.RequestException as e:print('Error:', e)# 获取代理IP
def get_proxy():try:# 代理IP的API地址api_url = 'http://api.ip.data5u.com/dynamic/get.html?order=YOUR_ORDER_NUMBER&ttl=1&json=1'response = requests.get(api_url)# 解析返回的JSON数据data = response.json()# 提取代理IP和端口号proxy_ip = data['data'][0]['ip']proxy_port = data['data'][0]['port']# 构造代理IP字典proxy = {'http': f'http://{proxy_ip}:{proxy_port}','https': f'https://{proxy_ip}:{proxy_port}',}return proxyexcept requests.exceptions.RequestException as e:print('Error:', e)# 测试代理IP是否可用
def test_proxy(proxy):try:# 使用httpbin.org作为测试目标网站url = 'http://httpbin.org/ip'response = requests.get(url, proxies=proxy)# 解析返回的JSON数据data = response.json()# 提取IP地址ip = data['origin']print('Proxy IP:', ip)except requests.exceptions.RequestException as e:print('Error:', e)# 主函数
def main():# 获取代理IPproxy = get_proxy()if proxy:# 测试代理IP是否可用test_proxy(proxy)# 使用代理IP访问网页url = 'https://www.example.com'html = request_with_proxy(url, proxy)print(html)if __name__ == '__main__':main()

确保将YOUR_ORDER_NUMBER替换为在代理IP网站上获得的订单号。在上述代码中,我们使用httpbin.org作为测试网站,可以将url变量替换为任何想要访问的实际网站。

好了,到这里就是今天的全部内容了,如有帮助不胜荣幸。

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

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

相关文章

HTTP网络相关知识

1 第一步: URI(统一资源标识符) URL(统一资源定位符)URN(统一资源名称); 2 传输协议: HTTP: 超文本传输协议 HTTPS: HTTP SSL(加密证书)相对于…

使用Vue3 + Vite创建uni-app项目(Webstorm)

使用Vue3 Vite创建uni-app项目(Webstorm) 参考:前端VUE3Vite UniAPP-- 框架搭建_uniapp vite-CSDN博客 // 参考github.com的库:https://github.com/dcloudio/uni-preset-vue npx degit dcloudio/uni-preset-vue#vite-ts vite-vu…

【SQL】delete 与 truncate 命令的区别

区别 truncatedelete属于 DDL(数据定义语言) 范畴属于 DML(数据操作语言) 范畴删除表数据,不能删除视图数据删除表数据,删除视图数据只可以梭哈删除通过 where 进行选择性删除不涉及事务处理删除表中数据涉及事务处理效率高、但无法撤销效率低&#xff…

【mars3d】new mars3d.layer.GeoJsonLayer({实现多孔面遮罩mask: true,

【mars3d】new mars3d.layer.GeoJsonLayer({实现多孔面遮罩 官网测试示例: 1.功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 测试代码: export function showDraw(isFlyTo) { removeLayer() const geoJsonLayer new mars3d.layer.GeoJsonLaye…

神经网络-搭建小实战和Sequential的使用

CIFAR-10 model structure 通过已知参数(高、宽、dilation1、kernel_size)推断stride和padding的大小 网络 import torch from torch import nnclass Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.conv1 nn.Conv2d(in_chan…

TSConfig 配置(tsconfig.json)

详细总结一下TSConfig 的相关配置项。个人笔记,仅供参考,欢迎批评指正! 另外,如果想了解更多ts相关知识,可以参考我的其他笔记: vue3ts开发干货笔记ts相关笔记(基础必看)ts相关笔记…

LeetCode-有效的字母异位词(242)

题目描述: 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。 思路: 这题还是比较简单的,首先将两个字符…

快乐学Python,Python基础之代码复用?「函数」

上一篇文章中,我们了解了代码的分支结构(if 家族语句)和循环结构(for 循环和 while 循环)。通过了解这些结构,我们已经能够写出稍微复杂一些的代码。但当代码一多,就会遇到一些问题。 上一篇文…

盖子的c++小课堂——第二十三讲:背包问题

前言 又是一次漫长的更新(我真不是故意的aaaaaaaaaaaaaaa),先不多说了,直接给我~坐下~说错了说错了,直接开始~ 背包问题----动态规划 背包问题(knapsack problem) 动态规划(dyna…

基于python的leetcode算法介绍之动态规划

文章目录 零 算法介绍一 例题介绍 使用最小花费爬楼梯问题分析 Leetcode例题与思路[118. 杨辉三角](https://leetcode.cn/problems/pascals-triangle/)解题思路题解 [53. 最大子数组和](https://leetcode.cn/problems/maximum-subarray/)解题思路题解 [96. 不同的二叉搜索树](h…

企业出海数据合规:GDPR中的个人数据与非个人数据之区分

GDPR仅适用于个人数据,这意味着非个人数据不在其适用范围内。因此,个人数据的定义是一个至关重要的因素,因为它决定了处理数据的实体是否要遵守该法规对数据控制者规定的各种义务。尽管如此,什么是个人数据仍然是当前数据保护制度…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -小程序首页实现

锋哥原创的uniapp微信小程序投票系统实战: uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

Docker 镜像以及镜像分层

Docker 镜像以及镜像分层 1 什么是镜像2 Docker镜像加载原理2.1 UnionFs:联合文件系统2.2 Docker镜像加载原理2.3 Docker镜像的特点 3 镜像的分层结构4 可写的容器层 1 什么是镜像 镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行…

数据处理四 基于图像hash进行数据整理(删除重复图片、基于模版查找图片)

一、背景知识 1.1 什么是hash Hash,一般翻译做“散列”,也有直接音译为“哈希”的,基本原理就是把任意长度的输入,通过Hash算法变成固定长度的输出。这个映射的规则就是对应的Hash算法,而原始数据映射后的二进制串就…

程序员必知!命令模式的实战应用与案例分析

命令模式是一种行为设计模式,它将请求封装为对象以实现客户端参数化、请求排队、日志记录及撤销操作,旨在解耦调用者与操作实现者,以智能家居为例,用户通过界面发送命令对象,设备作为接收者执行相应操作,无…

Ubuntu 安装Nginx服务

文章目录 前言一、Nginx安装1. Nginx默认安装2. Nginx指定版本安装3. Nginx验证4. Nginx服务控制4.1 查看服务状态4.2 停止服务4.3 启动服务4.4 重启服务 5. Nginx文件存放目录 二、自己编译Nginx1. 下载源码2. 依赖配置3. 编译 三、Nginx卸载总结 前言 Nginx(发音为…

SDN和NFV最明显的区别,SDN和传统网络有什么区别

目录 SDN和NFV最明显的区别是 SDN和传统网络有什么区别 一、SDN概述 1.1 S

Fixed win size sliding window

这篇记录灵神题单中的定长滑窗环节,不跟之前的Sliding Window一起了。 1. LC 1423 可获得的最大点数 这题其实有点思维的。实现上简单。 每次从首或者尾部拿,总共拿k次。相当于有n-k张牌不拿。因为不可能从中间截断着拿,因此必然这n-k张牌…

分布式(2)

目录 6.Ribbon和Feign的区别有哪些? 7.SpringCloud和dubbo有什么区别? 8.服务注册和发现是什么意思?SpringCloud如何实现? 9.介绍下网关的作用? 10.谈谈服务降级,熔断,服务隔离?…

机器学习(四) -- 模型评估(3)

系列文章目录 机器学习(一) -- 概述 机器学习(二) -- 数据预处理(1-3) 机器学习(三) -- 特征工程(1-2) 机器学习(四) -- 模型评估…