补环境
吐环境
1.Proxy对象
Proxy对象由两个部分组成:target、handler
target:目标对象
handler:是一个对象,声明了代理target的指定行为,支持的拦截操作,一共13种:
get(target,propKey,receiver)
:拦截对象属性的读取。target
: 目标对象propKey
: 被获取的属性名。receiver
: Proxy 或者继承 Proxy 的对象
set(target,propKey,value,receiver)
:拦截对象属性的设置,返回一个布尔值(修改成功)。target
: 目标对象propKey
: 被获取的属性名。value
: 新属性值。receiver
: Proxy 或者继承 Proxy 的对象
一般的补环境的是通过运行程序后的undefined报错去一点一点分析,一点一点的去补一些环境.
所以我们使用 Proxy 对全局遍历window、document、navigator等常见环境检测点进行代理,拦截代理对象的读取、函数调用等操作,并通过控制台输出,这样的话我们就能够实现检测环境自吐的功能,后续我们再针对吐出来的环境统一的进行补环境,这样就会方便的多。
2.案例
var target = {
name: 'XT',
age: 21,
aa: function () {
console.log(111)
}
};
//target是对象,handler是拦截操作
var p = new Proxy(target, {
//获取对象
get:function (target, propertyKey, receiver) {
//target 目标对象name:'JACK',age:'18'
// propertyKey :被获取属性的名字
// receiver 代理的对象
console.log(target)
console.log(propertyKey)
console.log(receiver)
console.log(target, propertyKey, receiver)
},
// //设置对象
// set: function (target,propertyKey,value,receiver) {
// // target 目标对象
// // propertyKey 设置的属性
// // value 设置的属性值
// // receiver 代理器对象
// console.log(target,propertyKey,value,receiver)
// }
})
console.log(p.name);
// p.user = 'aa'
返回结果
案例2
在这段代码中,target
是被 Proxy
包装的原始对象,propertyKey
是被访问或设置的属性名,而 receiver
是最初被调用的对象,通常是代理对象本身。
在实际的浏览器环境中,例如 window
、document
、navigator
等,这些参数的含义如下:
-
target:
target
是Proxy
构造函数的第一个参数,它是原始对象,即你想要对其进行代理的对象。在浏览器环境中,如果你创建了window
、document
或navigator
的代理,target
就会是这些全局对象之一。
-
propertyKey:
propertyKey
是被访问或设置的属性的名称。在浏览器环境中,如果你尝试访问window.location
或document.title
,propertyKey
将分别是"location"
和"title"
。
-
receiver:
receiver
是最初被调用的对象,通常是代理对象本身。在get
或set
陷阱(trap)中,receiver
是最初被调用的对象,它可以是代理对象或继承代理对象的任何对象。
以下是一个实际的例子,展示了如何在浏览器环境中使用 Proxy
来代理 window
对象,并记录属性的访问:
// 原始的 window 对象
var target = window;
// 创建一个代理来拦截对 window 对象的访问
var p = new Proxy(target, {
get: function (target, propertyKey, receiver) {
console.log('访问属性:', propertyKey);
// 返回原始属性值
return Reflect.get(target, propertyKey, receiver);
},
set: function (target, propertyKey, value, receiver) {
console.log('设置属性:', propertyKey, '值:', value);
// 设置原始属性值
return Reflect.set(target, propertyKey, value, receiver);
}
});
// 通过代理访问和设置属性
console.log(p.location.href); // 访问属性: location
p.document.title = '新标题'; // 设置属性: title 值: 新标题
在这个例子中,当通过代理对象 p
访问 location.href
时,get
陷阱会被触发,并打印出 "访问属性: location"
。然后,当通过 p
设置 document.title
时,set
陷阱会被触发,并打印出 "设置属性: title 值: 新标题"
。
请注意,直接对全局对象如 window
、document
或 navigator
使用 Proxy
可能会导致意外的副作用,因为这些对象通常由浏览器管理,并且它们的行为可能依赖于内部状态和上下文。在实际开发中,应谨慎使用 Proxy
来代理这些全局对象。
A股市场同花顺
确定需求:
这里我只爬取序号,代码,名称,现价,涨跌幅这几个字段。并实现翻页功能。
cookie反爬!!!
1.通过油猴脚本找到变化的cookie值
吐环境报错可能是因为之前的方法为空。
TypeError: n.attachEvent is not a function
通过打断点的方式,可以发现q的值是true,所以在浏览器环境中,它使用的是addEventListener方法,而不是attachEvent方法。
那么node环境中报错显示attachEvent undefined,说明q的值是False。这里我们验证一下
可以看到q确实是False。那么我们就直接补q,给q赋值
我们补充addEvenListener方法。
方法: set 对象: window 属性: addEventListener 属性类型: string 属性值类型: undefined
方法: set 对象: window 属性: addEventListener 属性类型: string 属性值类型: function
方法: get 对象: window 属性: document 属性类型: string 属性值类型: undefined
方法: get 对象: window 属性: addEventListener 属性类型: string 属性值类型: object
调用生成cookie值的方法时候,报错。这时,要把所有undefined的对象属性补齐。
补navigator
分析网页信息
确定S生成的位置
找到报错的问题点
再次尝试补document对象中的documentEelement属性,发现程序跑通了。
# 使用BeautifulSoup解析HTML内容
soup = BeautifulSoup(html_content, 'html.parser')
# 找到表格
table = soup.find('table', class_='m-table m-pager-table')
# 初始化一个列表来存储提取的数据
extracted_data = []
# 遍历表格中的所有行
for row in table.find_all('tr'):
# 获取当前行的所有单元格
cols = row.find_all('td')
# 如果单元格的数量正确,提取数据
if len(cols) == 5:
# 提取序号,代码,名称和现价
serial_number = cols[0].text.strip()
code = cols[1].text.strip()
name = cols[2].text.strip()
current_price = cols[3].text.strip()
# 将提取的数据添加到列表中
extracted_data.append({
'序号': serial_number,
'代码': code,
'名称': name,
'现价': current_price
})
结果
报错
加入翻页逻辑之后。有时候会出现这种报错,说明是被反爬了,之后会尝试解决一下