0
点赞
收藏
分享

微信扫一扫

马蜂窝游记爬虫实例

大南瓜鸭 2022-03-26 阅读 27

直接get(url)会返回521, 该网站采用了js加密反爬. 其实就是一个js逆向问题, 我们看到的是521, 实际上是进行了三次访问. 每次访问需要带上上一次的cookie.

  • 先导入库和设置一个头部
import re
import execjs
import requests
import json
from requests.utils import add_dict_to_cookiejar
from requests.packages.urllib3.exceptions import InsecureRequestWarning
# 关闭ssl验证提示
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
header = 
{
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0',
    'Host' : 'www.mafengwo.cn'
}
  • 进行第一次访问
session = requests.session() #使用session会一直携带上一次的cookies
url = 'https://www.mafengwo.cn/i/23463414.html'
response = session.get(url, headers=header, verify=False) #直接访问得到JS代码
js_clearance = re.findall('cookie=(.*?);location', response.text)[0] #用正则表达式匹配出需要的部分
# 
result = execjs.eval(js_clearance).split(';')[0].split('=')[1] #反混淆、分割出cookie的部分
print(result)

结果为:
在这里插入图片描述
这就是第一次访问后得到的解析过的cookie.

  • 进行第二次访问
add_dict_to_cookiejar(session.cookies, {'__jsl_clearance_s': result})  #将第一次访问的cookie添加进入session会话中
response = session.get(url, headers=header, verify=False) #带上更新后的cookie进行第二次访问

会得到以下内容:
在这里插入图片描述
内容很乱, 但是没关系, 用我们之前提到的JS美化小工具在线JS格式化. 将上述本文粘贴进这个工具进行格式化, 再拉到最后
在这里插入图片描述
可以看到这次访问有个go函数, 其中一个attrs为**“ha”**, 这是hash(哈希)加密算法的简称, 此次哈希算法函数为sha256, 实际上这类反爬虫只有三种算法函数 sha256、sha1、md5. 那么只需要根据此次访问的加密类型来反解cookie即可.
我们将go函数部分提取出来

go = json.loads(re.findall(r'};go\((.*?)\)</script>', response.text)[0])

结果:
在这里插入图片描述
根据算法规则反解cookie

for i in range(len(go['chars'])):
    for j in range(len(go['chars'])):
        values = go['bts'][0] + go['chars'][i] + go['chars'][j] + go['bts'][1]
        if go['ha'] == 'md5':
            ha = hashlib.md5(values.encode()).hexdigest()
        elif go['ha'] == 'sha1':
            ha = hashlib.sha1(values.encode()).hexdigest()
        elif go['ha'] == 'sha256':
            ha = hashlib.sha256(values.encode()).hexdigest()
        if ha == go['ct']:
            __jsl_clearance_s = values

原理是就是正确的cookie由go函数中的"bts", "chars"里的字符所组成, 但网页返回的是哈希值, 所以当我们确定好加密方式后, 只需要将所有组合的哈希值计算然后与正确的配对, 就能找到正确的cookie.

  • 第三次访问
    将第二次访问中哈希算法得到的cookie再一次添加到session会话中, 进行第三次访问
add_dict_to_cookiejar(session.cookies, {'__jsl_clearance_s' :__jsl_clearance_s})
response = session.get(url, headers=header, verify=False)
response.text

结果
在这里插入图片描述
就能够得到正确的页面信息了.


另一个思路: 将三种算法函数保存到本地, 判断出是哪种加密算法后, 将哈希值带入, 反解出cookie

import re
import execjs
import requests
import json
from requests.utils import add_dict_to_cookiejar
from requests.packages.urllib3.exceptions import InsecureRequestWarning

# 关闭ssl验证提示
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0',
}
url = 'https://www.mafengwo.cn/i/23463414.html'
# 使用session保持会话
session = requests.session()


def get_parameter(response):
    # 提取js代码
    js_clearance = re.findall('cookie=(.*?);location', response.text)[0]
    # 执行后获得cookie参数js_clearance
    result = execjs.eval(js_clearance).split(';')[0].split('=')[1]
    # 添加cookie
    add_dict_to_cookiejar(session.cookies, {'__jsl_clearance_s': result})
    # 第二次请求
    response = session.get(url, headers=header, verify=False)
    # 提取参数并转字典
    parameter = json.loads(re.findall(r';go\((.*?)\)', response.text)[0])
    js_file = ''
    # 判断加密方式
    if parameter['ha'] == 'sha1':
        js_file = 'sha1.js'
    elif parameter['ha'] == 'sha256':
        js_file = 'sha256.js'
    elif parameter['ha'] == 'md5':
        js_file = 'md5.js'
    return parameter, js_file


def get_cookie(param, file):
    with open(file, 'r') as f:
        js = f.read()
    cmp = execjs.compile(js)
    # 执行js代码传入参数
    clearance = cmp.call('go', param)
    return clearance


def run():
    # 第一次请求
    response = session.get(url, headers=header, verify=False)
    # 获取参数及加密方式
    parameter, js_file = get_parameter(response)
    # 获取cookie
    clearance = get_cookie(parameter, js_file)
    print(clearance)
    # 修改cookie
    add_dict_to_cookiejar(session.cookies, {'__jsl_clearance_s': clearance})
    # 第三次请求
    html = session.get(url, headers=header, verify=False)
    #print(html.cookies)
    #print(html.content.decode())
    return html
    
page = run()
soup = BeautifulSoup(page.text, "html.parser")
soup

结果
在这里插入图片描述
也同样能获得正确的页面

举报

相关推荐

0 条评论