Python爬虫入门与登录验证自动化思路

news2024/10/7 20:24:33

1、pytyon爬虫

1.1、爬虫简介

Python爬虫是使用Python编写的程序,可以自动访问网页并提取其中的信息。爬虫可以模拟浏览器的行为,自动点击链接、填写表单、进行登录等操作,从而获取网页中的数据。

使用Python编写爬虫的好处是,Python具有简单易学的语法和丰富的库资源,使得编写爬虫程序变得相对容易。Python中有一些常用的爬虫库,如Requests、BeautifulSoup、Selenium等,可以帮助我们更加方便地进行网页访问、数据提取和处理。

爬虫的应用非常广泛,可以用于网页数据的抓取、信息的分析、自动化测试等等。但是需要注意的是,在使用爬虫时,应遵守网站的相关规定,不进行恶意攻击和滥用。

1.2、python基本知识点与困难点

使用爬虫最基本知识点

  1. request:使用reqeust发起http请求
  2. json:解析http请求的返回数据
  3. Regular expressions:利用正则表达式深度挖掘提取字符串的匹配数据

爬虫工具最难的地方在于登录验证,只要登录通过,拿到token,其他的工作只不过是一些体力活。

2、爬虫简单请求

爬虫最简单的案例,无非是手动登录之后,通过chrome开发者工具,拿到http请求地址,再模拟数据请求。以下是一个简单的案例——获取csdn专栏文章数据

2.1、手动登录并获取目标http地址

1.人工登录csdn网站。

2.点击专栏管理,选择其中一个专栏

3.点击开发者工具,chrome浏览器使用F12快捷键 ,可以拿到具体的http地址

4.使用python进行http访问

import requests

# 目标URL
url = '这里填写目标http地址'
response = requests.get(url)
print(response.text)

执行之后,发现有报错。

{
  "message":"X-Ca-Key is not exist"
}

2.2、网站反爬基本原理

网站服务器对于一个http请求,会先检测是否已经登录授权过,若没有,则跳转到登录页面。

服务器在验证登录之后,会生成一个token(token里带有用户个人信息,例如JWT算法)。

客户端登录之后,会在发送的每一个请求都带上token信息(附加到http header)。

2.3、带上header重新进行访问

在开发者工具,查看header信息

由于不知道服务器具体验证哪些参数,最保险的是,把所有header参数到带上。具体参数自行填写。

import json

import requests

# 目标URL
url = 'http------'


# # 定义你的header信息
headers = {
    'authority': 'bizapi.csdn.net',
    'method': 'GET',
    'path': 'path--------',
    'scheme': 'https',
    'Accept': 'application/json, text/plain, */*',
    'Accept-Encoding': 'gzip, deflate, br, zstd',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cookie': 'token--------',
    'Origin': 'https://mp.csdn.net',
    'Priority':'u=1, i',
    'Referer': 'Referer------',
    'Sec-Ch-Ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
    'Sec-Ch-Ua-Mobile': '?0',
    'Sec-Ch-Ua-Platform': '"Windows"',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-site',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
    'X-Ca-Key':'------',
    'X-Ca-Nonce':'------',
    'X-Ca-Signature':'------',
    'X-Ca-Signature-Headers':'x-ca-key,x-ca-nonce'
}

response = requests.get(url, headers=headers)
print(response.text)
data=json.loads(response.text)['data']
print("专栏名称:",data["category_info"]["title"])
print("专栏介绍:",data["category_info"]["desc"])
articles=data["category_article_list_unTop"]
for article in articles:
    print("文章id",article["id"],"文章标题", article["title"])

再结合json工具,即可看到请求数据了

专栏名称: 从java到python
专栏介绍: 从Java到Python专栏,旨在帮助那些已经掌握Java编程语言的开发者快速了解并过渡到Python编程语言。对于一个开发者,一定要有一门主攻并且精通的编程语言,这里,在学习新语言的时候,可以横向对比,加深加快对编程的认知。
文章id 44793029 文章标题 Python多线程编程
文章id 44792996 文章标题 Python包管理工具
文章id 44743210 文章标题 Python反射
文章id 44734516 文章标题 Python将Json转为对象
文章id 44718294 文章标题 Python面向对象
文章id 44718286 文章标题 Python多元赋值
文章id 44530690 文章标题 Python之推导式
文章id 44529667 文章标题 Python基本类型
文章id 44520951 文章标题 Python属于动态强类型语言
文章id 44520978 文章标题 第一个Python程序

3、自动化登录

网站爬虫与反爬虫之间的对战是一场持续的技术较量。爬虫开发者试图尽可能多地从网站上抓取信息,而网站开发者则试图保护他们的数据不被非法或过度抓取。

本文所介绍的反爬虫策略只是用来演示和学习,而不会对网站进行破坏。因此,只提供一些伪代码,而隐藏真实网站的相关信息

3.1、网站登录图片验证方式

网站登录的时候,除了输入账号密码之外,还可能需要进行一些图片验证,例如下图。

常见的验证方式有: 

  1. 图片选择:要求用户在一组图片中选择特定的图片或者按照特定的要求进行图片排序,例如选择包含某个物体的图片、选择与某个图片相似的图片等。
  2. 图片拼图:要求用户拖动或旋转图片,将图片拼合成完整的图像。
  3. 图片识别:要求用户根据提供的图片中的验证码或文字进行识别,例如输入图片中显示的文字或数字。
  4. 逻辑判断:要求用户根据一组图片中的某种规律或者某种共同特征进行判断,例如选择与其他图片不同的图片、选择与指定要求相符的图片等。

对于这些验证方式,爬虫有两种方式进行处理。

第一种半自动化:爬虫工具自动拉取浏览器,自动输入账号密码之后,由用户手动输入验证码,拿到token后再进行数据爬取。

第二种全自动化:爬虫工具自动拉取浏览器,利用打码平台(平台自身使用ai训练或雇佣人工操作),由第三方进行验证返回识别结果,拿到token。

本文主要讲解第二种识别方法。

3.2、使用打码平台自动识别验证码

验证码打码平台是一种在线服务,它可以帮助用户自动识别和解析各种形式的验证码。这些验证码通常是为了验证用户的真实性或防止恶意活动而设置的。打码平台通过使用机器学习和人工智能算法来识别和解析这些验证码,然后将结果返回给用户。用户可以通过API接口或者网站上传验证码图片,并获取解析结果。这些平台通常提供高度准确的解析结果和快速的响应时间,使用户能够更有效地处理验证码。

比如下面一款打码平台,可识别大部分验证码类型。

基本登录

对于自动输入账号,密码,我们可以使用Selenium工具。

Selenium是一个开源的自动化测试框架,用于测试Web应用程序的功能。它提供了一系列工具和库,可以让开发者模拟用户在浏览器中的操作,例如点击、输入文本、选择元素等。Selenium支持多种编程语言,包括Java、Python、C#等,使开发者能够根据自己的喜好和需求选择合适的语言进行测试脚本的编写。

示例代码如下:

# 指定 ChromeDriver 的路径
driver_path = 'chromedriver.exe'
# 创建 WebDriver 实例
driver = webdriver.Chrome()
driver.maximize_window()

def login_form():
    # 打开一个网页
    driver.get('https://xxx.login')
    driver.implicitly_wait(5)
    driver.find_element(By.ID, 'username').send_keys('jforgame')
    driver.find_element(By.ID, 'pwd').send_keys('jforgame')

3.3、获取验证码图片

一般情况下,验证码图片比较容易获得,只需从chrome调试网络工具查看请求的地址,再根据这个url重新请求一下图片后进行本地保存即可。

部分网站提供了更加安全的措施,为了反爬虫,对于生成的图片是一次性的。每次请求图片的url,返回的图片内容都是不同的。如此很难拿到已经发送到客户端的图片了。但方法也是有的,大致有以下几种策略。
拦截一次性验证码图片策略

  1. 网站连接到自己写的http代理服务器,每次请求,如果是图片则同时将网站返回的图片内容保存到本地。这种方式如果是网站使用了https方式,这种代理代码不好实现。
  2. 爬虫自动控制浏览器,定位到图片位置,使用右键进行保存。selenium只支持定位到图片位置,并点击右键,但无法继续触发右键的另存为操作,失败。
  3. 简单笨拙的方法,爬虫直接截取屏幕指定范围的图片,只需慢慢调整截图的位置坐标,可以实现。python有pyautogui工具库可以使用,示例代码如下:
# 定位到图片元素
imgEle = driver.find_element(By.XPATH, '//*[@id="capture"]/img')

#顶点横坐标
left = 500
#顶点纵坐标
top = 400
width = 200
height = 150

def save_screenshot():
    # 截取屏幕并保存为文件
    screenshot = pyautogui.screenshot(region=(left, top, width, height))
    screenshot.save('screenshot.jpeg')

3.4、将图片发送到打码平台进行解析

网上有很多打码平台,读者可自行选择,一般平台都提供测试积分,测试合适再进行选择。将返回结果封装成坐标元组即可。下面以点击类验证码做演示:

    def ydm():
        url = 'http://api.xxxxx/analyze'
        image_path = "screenshot.jpeg"  # 替换为实际图片路径
        image_data = image_to_base64(image_path)
        data = {
            'image': image_data,
            'token': 'copy your platform token here',
            'type': 10086
        }
        # 发送请求
        response = requests.post(url, data=data)
        response_json = response.text
        obj = json.loads(response_json)

        if obj['msg'] == "succ":
            pos_data = obj['data']['data']
            print('识别成功')
            for _, e in enumerate(pos_data.split('|')):
                unit = e.split(",")
                pos_list.append((int(unit[0]), int(unit[1])))
            return pos_list
        else:
            print(response_json)
            return None

3.5、根据解析坐标向平台发送登录请求。

拿到点击坐标之后,还没完成目标。一些网站对坐标的输入进行加密,只有把坐标信息经过加密后服务器才认可。虽然浏览器代码是裸奔的,但要解读加密算法需要一定功力。我们可以换个思维——无招胜有招

既然验证码加密了,我们也无需解密。直接祭上我们的selenium工具,利用自动化测试工具,模拟用户进行点击,由于selenium直接操作浏览器,由浏览器客户端代码自行发送请求,就无需解密了。

def auto_click_capture():
    try_counter = 0
    while try_counter < max_try:
        pos_list = ydm()
        for _, pos in enumerate(pos_list):
            time.sleep(1)
            ActionChains(driver).move_to_element_with_offset(imgEle, pos[0],pos[1]).click().perform()
        try:
            # 如果页面检测到登录按钮,则脚本成功
            login_btn = driver.find_element(By.ID, 'loginBtn')
            login_btn.click()
            return
        except Exception:
            try_counter = try_counter + 1
            print(f"第{try_counter}次尝试,未找到")
            time.sleep(1)

由于网站有些图片尺寸比较小,或者图片加了旋转,打码平台返回的坐标不是很精准。一次性成功的机率不高,我们可以加多一次重试。

3.6、自动获取网站登录token

登录成功之后,我们希望自动获取到网站的登录token,而不是通过网络工具手动复制参数。selenium对此无能为力,我们可以使用selenium的增强版seleniumwire。seleniumwire增加了拦截http请求响应的功能,并完全兼容selenium。下载之后只需修改import的webdriver路径即可。

not_found = True
token = ''

while not_found:
    for request in driver.requests:
        if request.response and request.url.find("xxyy/loginIn"):
            # print(    request.url,request.response.headers)
            for i, item in enumerate(request.response.headers.items()):
                if item[0] == 'set-cookie' and item[1].find('JWT_SESSION') != -1:
                    JWT_SESSION= match_inner_characters(r"JWT_SESSION=(.*?);", item[1])
            print("JWT_SESSION", JWT_SESSION)
    matchContent = match_inner_characters(r"___TOKEN=(.*)", JWT_SESSION)
    if matchContent:
        not_found = False
        token = matchContent.replace("; Path=/", "")
        cookies = '自行封装其他额外token信息'
    time.sleep(3)

print('Cookies ', cookies)
print('token', token)

拿到token和cookies信息,大功告成!

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

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

相关文章

[数据集][目标检测]足球场足球运动员身份识别足球裁判员数据集VOC+YOLO格式312张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;312 标注数量(xml文件个数)&#xff1a;312 标注数量(txt文件个数)&#xff1a;312 标注类别…

LeetCode | 1624.两个相同字符之间的最长子字符串

这道题拿到手想法就是去双重遍历暴力解&#xff0c;对于每个字符&#xff0c;从后往前遍历字符串&#xff0c;找到从后往前一直到本次遍历的这个字符串这段子串中和这个字符串相同的字符位置&#xff0c;然后得到子字符串的长度&#xff0c;和ans存储的值做一个比较&#xff0c…

umap降维,c++用法纪实

全是血泪&#xff0c;可惜对于大量数据&#xff0c;速度还是太慢。 一、代码 // ConsoleApplication2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //#include <iostream>#include "knncolle/knncolle.hpp" #include "Umap.…

MSPM0l1306——配置滴答定时器

我们配置好了滴答定时器之后&#xff0c;还要手动编写滴答定时器的中断服务函数&#xff0c;因为我们开启的滴答定时器的中断&#xff0c;当滴答定时器的计数值从我们设置的值减到0时&#xff0c;就会触发一次中断&#xff0c;触发中断就会执行中断服务函数。各个中断的中断服务…

Bio-Info每日一题:Rosalind-05-Computing GC Content

&#x1f389; 进入生物信息学的世界&#xff0c;与Rosalind一起探索吧&#xff01;&#x1f9ec; Rosalind是一个在线平台&#xff0c;专为学习和实践生物信息学而设计。该平台提供了一系列循序渐进的编程挑战&#xff0c;帮助用户从基础到高级掌握生物信息学知识。无论你是初…

python开发扑克牌游戏

用一个列表保存54张扑克牌&#xff0c;先洗牌,再按斗地主的发牌方式把牌发给三个玩家&#xff0c;多的3张牌给第一个玩家(地主)最后把每个玩家手上的牌显示出来。 import random# 定义卡牌列表 cards [] # 定义花色列表 suites [黑桃, 红心, 草花, 方块] # 定义点数列表 fac…

牛客热题:最长公共子序列Ⅱ

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;最长公共子序列Ⅱ题目链接方法一…

QT串口调试助手V2.0(源码全开源)--上位机+多通道波形显示+数据保存(优化波形显示控件)

首先关于Qt的安装和基本配置这里就不做重复说明了&#xff0c;注&#xff1a;本文在Qt5.14基础上完成 完整的项目开源仓库链接在文章末尾 图形控件——qcustomplot QCustomPlot是一个基于Qt框架的开源绘图库&#xff0c;用于创建高质量的二维图表和数据可视化。 QCustomPlot…

IO-源码阅读 glibc 2.35

文章目录 参考缓存机制IO_FILE_PLUSfopenfopen_internal_IO_no_init_IO_old_init _IO_new_file_init_internal_IO_link_in _IO_new_file_fopen_IO_file_open fread_IO_fread_IO_sgetn_IO_doallocbuf_IO_file_doallocate_IO_file_stat_IO_setb __underflow_IO_new_file_underflo…

windows软件手动设置开机自启

博主需求 由于很多线上课程使用outlook进行教学&#xff0c;课程链接都关联到outlook日历中了&#xff0c;只要保持outlook是打开的状态就能收到上课提醒&#xff0c;非常方便。 但是有时候会忘记打开outlook查看&#xff0c;我偶尔会错过一些提醒QAQ。 所以如何让outlook常…

Qwen2大模型微调入门实战(完整代码)

Qwen2是通义千问团队的开源大语言模型&#xff0c;由阿里云通义实验室研发。以Qwen2作为基座大模型&#xff0c;通过指令微调的方式实现高准确率的文本分类&#xff0c;是学习大语言模型微调的入门任务。 指令微调是一种通过在由&#xff08;指令&#xff0c;输出&#xff09;对…

解读下/etc/network/interfaces配置文件

/etc/network/interfaces 是一个常见的网络配置文件&#xff0c;通常在 Debian 及其衍生版本的 Linux 发行版中使用。该文件用于配置网络接口和网络连接参数&#xff0c;允许用户手动设置网络连接的属性&#xff0c;包括 IP 地址、子网掩码、网关、DNS 服务器等。 以下是一个可…

LeetCode热题100—链表(二)

19.删除链表的倒数第N个节点 题目 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a; 输入&#xff1a;head [1], n 1 …

人工智能程序员应该有什么职业素养?

人工智能程序员应该有什么职业素养&#xff1f; 面向企业需求去学习AI必备技能实战能力实战能力提升策略 面向企业需求去学习 如果想要应聘AI相关的岗位&#xff0c;就需要知道HR和管理层在招聘时需要考察些什么&#xff0c;面向招聘的需求去学习就能具备AI程序员该有的职业素…

Golang发送邮件如何验证身份?有哪些限制?

Golang发送邮件需要哪些库&#xff1f;怎么设置邮件发送的参数&#xff1f; 对于开发者而言&#xff0c;使用Golang发送邮件是一种常见需求。然而&#xff0c;在发送邮件的过程中&#xff0c;验证身份是一个至关重要的环节&#xff0c;它确保了邮件的可靠性和安全性。A将探讨G…

linux业务代码性能优化点

planning优化的一些改动----------> 减少值传递&#xff0c;多用引用来传递 <---------- // ----------> 减少值传递&#xff0c;多用引用来传递 <---------- // 例1&#xff1a; class A{}; std::vector<A> v; // for(auto elem : v) {} // 不建议&#xff…

FreeRTOS实时系统 在任务中增加数组等相关操作 导致单片机起不来或者挂掉

在调试串口任务中增加如下代码&#xff0c;发现可以用keil进行仿真&#xff0c;但是烧录程序后&#xff0c;调试串口没有打印&#xff0c;状态灯也不闪烁&#xff0c;单片机完全起不来 博主就纳了闷了&#xff0c;究竟是什么原因&#xff0c;这段代码可是公司永流传的老代码了&…

【小白专用24.6.8】c#异步方法 async task调用及 await运行机制

await是C#中用于等待异步操作完成的关键字。它通常用于异步方法内部&#xff0c;使得在等待异步操作期间&#xff0c;线程可以继续执行其他操作&#xff0c;从而保持程序的响应性。 在使用await时&#xff0c;需要注意以下几点&#xff1a; 1. async修饰符&#xff1a; 使用…

Mac环境下,简单反编译APK

一、下载jadx包 https://github.com/skylot/jadx/releases/tag/v1.4.7 下载里面的这个&#xff1a;下载后&#xff0c;找个干净的目录解压&#xff0c;我是放在Downloads下面 二、安装及启动 下载和解压 jadx&#xff1a; 下载 jadx-1.4.7.zip 压缩包。将其解压到你希望的目…

C++ 史上首次超越 C,跃至榜二

TIOBE 公布了 2024 年 6 月的编程语言排行榜。 C在本月的TIOBE指数中成功超越了C&#xff0c;成为新的第二名。它是一种被广泛应用于嵌入式系统、游戏开发和金融交易软件等领域的编程语言。这次的排名是C在TIOBE指数中的历史最高位&#xff0c;同时也是C语言的历史最低位。 T…