Python 爬虫从入门到放弃,网络爬虫应用实战

15 篇文章 1 订阅
12 篇文章 0 订阅


在这里插入图片描述

Request 库

get 方法

Python requests 库的 get()方法非常常用,可以用于获取网页的源码等信息,该方法的语法为:

requests.get(url, params=None, **kwargs)
参数说明
url拟获取页面的url链接
paramsurl中的额外参数,字典或字节流格式,可选
**kwargs12个控制访问的参数

除了 get() 方法,常用的方法有:

方法说明
requests.get()获取 HTML 网页的主要方法,对应于 HTTP 的 GET
requests.head()获取 HTML 网页头信息的方法,对应于 HTTP 的 HEAD
requests.post()向 HTML 网页提交 POST 请求的方法,对应于 HTTP 的 POST

Request 对象

当我们使用 get() 方法时,就会构造一个向服务器请求资源的 Request 对象。Request 对象的作用是与客户端交互,收集客户端的 Form、Cookies、超链接,或者收集服务器端的环境变量。request 对象是从客户端向服务器发出请求,包括用户提交的信息以及客户端的一些信息。客户端可通过 HTML 表单或在网页地址后面提供参数的方法提交数据,然后服务器通过 request 对象的相关方法来获取这些数据。

Response 对象

Response 对象用于动态响应客户端请示,控制发送给用户的信息,并将动态生成响应。get() 方法将会返回一个包含服务器资源的 Response 对象,response 对象的属性如下:

属性说明
r.status_codeHTTP请求的返回状态,200表示连接成功,404表示失败
r.textHTTP响应内容的字符串形式,即,url对应的页面内容
r.encoding从HTTP header中猜测的响应内容编码方式
r.apparent_encoding从内容分析出的响应内容编码方式(备选编码方式)
r.contentHTTP响应内容的二进制形式

session 会话对象

会话对象让你能够跨请求保持某些参数,它也会在同一个 Session 实例发出的所有请求之间保持 cookie。

所以如果你向同一主机发送多个请求,底层的 TCP 连接将会被重用,从而带来显著的性能提升。会话也可用来为请求方法提供缺省数据,这是通过为会话对象的属性提供数据来实现的。

定义一个 Session 实例语法为:

s = requests.Session()

正则匹配

Python 支持正则表达式,使用正则表达式可以匹配所需要的数据。下面看 2 个常用的方法。

re.match() 方法

re.match() 方法可以从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话 match() 就返回 none。

re.match(pattern, string, flags=0)
参数说明
pattern匹配的正则表达式
string要匹配的字符串
flags标志位

re.match 只匹配字符串的开始,如果字符串开始不符合正则表达式则匹配失败.而re.search 匹配整个字符串,直到找到一个匹配。

例题:bugku-web 基础 $_POST

题目的源码如下,需要用 POST 方法提交一个参数 what,值为 “flag”。

$what = $_POST['what'];
echo $what;
if($what == 'flag')
    echo 'flag{****}';

用 Python 的 requests 库的 post 方法提交一个字典上去,然后将对象输出查看。

import requests
 
value = {"what":"flag"}
r = requests.post("http://123.206.87.240:8002/post/",value)
r.text

例题:bugku-速度要快

打开网页,首先打开 F12,题目需要我们用 POST 提交一个什么东西。在这里插入图片描述
按照套路看一下响应头信息,其中有一个 flag 字段,值明显是个 base64 加密。在这里插入图片描述
拿去解密,这个应该就是需要交的东西了,不过它也是个 base64 加密后的字符串,二次解密得到 “553635”。在这里插入图片描述
使用 HackBar 用 POST 方法提交 margin 参数,但是没有得到答案?在这里插入图片描述
根据提示是我们操作得不够快,多抓几次包可以发现 flag 字段中的数据是不断在变化的。也就是说我们上传的 margin 参数需要和变化之前的 flag 值相匹配才行,若速度太慢 flag 值发生变化就无法得到答案。在这里插入图片描述在这里插入图片描述
在这里插入图片描述这个变化速度靠人力是做不到的,所以考虑使用 Python 爬虫。首先爬取网页获取响应头信息 headers,在 Python 中返回的是字典,使用 “flag” 为“键”可以获取该字段的值。在这里插入图片描述
接着使用 Python 自带的 base64 库使用 b64decode() 方法进行 base64 解码,截取 flag 部分进行二次解码。最后使用 post() 方法提交 margin 参数,输出返回的文本即可。

import requests
import base64
 
r = requests.Session()
headers = r.get("http://123.206.87.240:8002/web6/").headers
str = repr(base64.b64decode(headers['flag']))
str = base64.b64decode(str[str.find(":") + 2:])
data= {'margin':str}
flag = r.post("http://123.206.87.240:8002/web6/",data = data)
print(flag.text)

此处注意 2 个地方,第一是要先用 repr() 函数将对象转化为供解释器读取的形式,这样才能保证后面的代码可以处理数据。

第二是需要用 requests.Session() 创建一个 session 对象,session 对象能够让我们跨 http 请求保持某些参数,即让同一个 session 对象发送的请求头携带某个指定的参数。

爬虫和提交参数时,需要用同一个 session 对象来实现。

例题:bugku-秋名山老司机

打开题目,题目要求在 2s 之内计算出表达式的值。在这里插入图片描述
如果是人力来做的话非常困难。此时我们考虑用爬虫把网页爬下来,然后用正则表达式提取其中的表达式。在这里插入图片描述
但是怎么提交呢?继续刷新页面,得到提示用 POST 方法提交一个 value 变量。在这里插入图片描述
现在我们来写 Python 脚本,首先要用 requests.Session() 创建一个 session 对象,并且使用 get() 方法把网页爬下来。

接下来进行正则表达式匹配,使用 re.search() 方法实现。匹配的正则表达式书写格式为:r 表示字符串为原始字符串("" 不认为是转义字符),“\d+” 匹配一个或者多个字符,“[±*]” 匹配加号,加号,乘号,因为式子里面包含这三种运算,"-“ 在中括号里面为特殊符号,使用”"转义,最后 “\d+” 再匹配一个字符或者多个字符就满足了式子格式。

当然因为这个算式是在 div标签中的,因此正则匹配 div 标签也可以。综上所述,匹配的正则表达式为:

r'(\d+[+\-*])+(\d+)'
<div>(.*?)</div>

eval() 函数用来执行一个字符串表达式,并返回表达式的值。使用 eval() 函数计算出匹配到的表达式的值之后,用 post() 方法上传。

import requests
import re
 
s = requests.Session()
r = s.get("http://123.206.87.240:8002/qiumingshan/")
expression = re.search(r'(\d+[+\-*])+(\d+)', r.text)
value = eval(str(expression.group()))
data = {"value": value}
r = s.post("http://123.206.87.240:8002/qiumingshan/", data = data)
print(r.text)

例题:bugku-cookies 欺骗

首先打开网页,显示了一堆没用的东西,尝试过几种解码后放弃。注意到 url 中的 filename 的值为一段 base64 编码,解码后是 “keys.txt”。在这里插入图片描述
考虑到一般情况下在 index.php 之类的文件中有源码,因此把 “index.php” 的 base64 编码结果 “aW5kZXgucGhw” 当做参数穿过去。在这里插入图片描述
怎么还是什么都没有?注意到还有个 line 参数,根据字面意义来理解这个应该是指源码的行数。将 line 设置为 1,成功返回一句源码。在这里插入图片描述
也就是说,现在要通过设置 line 参数的值,以此获取源码。由于不知道具体有几行,可以写一个 Python 脚本来获取源码的所有行。

import requests
 
s = requests.Session()
for i in range(50):
    r = s.get("http://123.206.87.240:8002/web11/index.php?line="+ str(i) + "&filename=aW5kZXgucGhw")
    print(r.text)

成功获得源码如下,源码中知道了还有个 key.php 可以访问,但是需要 cookie 的内容为 margin = margin时才能访问。

<?php
error_reporting(0);
$file = base64_decode(isset($_GET['filename'])?$_GET['filename']:"");
$line = isset($_GET['line'])?intval($_GET['line']):0;
 
if($file=='')
    header("location:index.php?line=&filename=a2V5cy50eHQ=");
$file_list = array('0' =>'keys.txt','1' =>'index.php',);
 
if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin'){
    $file_list[2]='keys.php';
}
 
if(in_array($file, $file_list)){
    $fa = file($file);
    echo $fa[$line];
}

此时把 filename 的参数设置为 key.php 的 base64 编码 “a2V5LnBocA==”,然后用 HackBar 传递一个 cookie 过去,打开 F12 得到 flag。在这里插入图片描述
最后,感谢您的阅读。您的每个点赞、留言、分享都是对我们最大的鼓励,笔芯~

如有疑问,欢迎在评论区一起讨论!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值