无头浏览器(Headless browser)指没有用户图形界面的(GUI)的浏览器,目前广泛运用于web爬虫和自动化测试中。随着反爬虫和反反爬虫对抗技术的升级,越来越多的爬虫开始使用无头浏览器伪装成正常用户绕过反爬虫策略。
我们如何区分这些无头浏览器和正常浏览器?从Server Side分析用户行为进行检测是一劳永逸的方法,但成本和难度都很大。
不过通过无头浏览器的一些特性。我们也可以从从Client Side找出一些不同来。下面以醉受欢迎的PhantomJS(2.x版本)为例,介绍一些识别的方法,对于其他的无头浏览器,如Slimer JS这些方法也可以参考
Category Archives: C/C++
编译器的选择(x86_amd64, amd64等的区别)
编译器的选择(x86_amd64, amd64等的区别)
- 32/64 位系统编译,在32位系统上运行 => x86
- 32 系统上编译,在64位系统上运行 => x86_amd64
- 64 系统上编译,在64位系统上运行 => amd64
c++ 写入文件、读取文件
c++ 写入文件、读取文件
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
#include <iostream> #include <string> #include <fstream> using namespace std; // 写入 void write(char * filePath, char * data) { // 以写模式打开文件 ofstream outfile; outfile.open(filePath); cout << "Writing to the file" << endl; cout << "Enter your name: "; cin.getline(data, 100); // 向文件写入用户输入的数据 outfile << data << endl; cout << "Enter your age: "; cin >> data; cin.ignore(); // 再次向文件写入用户输入的数据 outfile << data << endl; // 关闭打开的文件 outfile.close(); } // 读取 void read(char * filePath, char * data) { // 以读模式打开文件 ifstream infile; infile.open(filePath); cout << "Reading from the file" << endl; infile >> data; // 在屏幕上写入数据 cout << data << endl; // 再次从文件读取数据,并显示它 infile >> data; cout << data << endl; // 关闭打开的文件 infile.close(); } int main() { char data[100]; char filePath[64] = "afile.dat"; // 写入 write(filePath, data); // 读取 read(filePath, data); system("pause"); return 0; } |
c++ 随机数
c++ 随机数
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <string> #include <random> #include <functional> // bind() using namespace std; int main() { random_device rd; mt19937 gen = mt19937(rd()); uniform_real_distribution<> dis(40, 100); auto randFun = bind(dis, gen); for(int i=0; i<5; i++) { cout << (int)randFun() << "\t" << (int)randFun() << "\t" << (int)randFun() << endl; } } |
Windows 系统编译 Redis 6.0.7 最新版
redis最新版本,windows系统最新版本redis
Redis5.0带来了Stream类型。从字面上看是流类型,但其实从功能上看,应该是Redis对消息队列(MQ,Message Queue)的完善实现。用过Redis做消息队列的都了解,基于Reids的消息队列实现有很多种,例如:
- PUB/SUB,订阅/发布模式
- 基于List的 LPUSH+BRPOP 的实现
- 基于Sorted-Set的实现
自己的一个小项目中,需要使用到Stream类型数据,所以,就要开始折腾了。 Continue reading
用Cygwin编译Redis源码包中的lua时报错:aix ansi bsd freebsd generic linux macosx mingw posix solaris
用Cygwin环境编译Redis源码包时,报错:
0 1 2 3 4 5 6 7 |
$ make cd src && make all make[1]: 进入目录“/home/delladmin/redis-6.0.7/src” LINK redis-server cc: 错误:../deps/lua/src/liblua.a:No such file or directory make[1]: *** [Makefile:283:redis-server] 错误 1 make[1]: 离开目录“/home/delladmin/redis-6.0.7/src” make: *** [Makefile:6:all] 错误 2 |
意思是要进入目录/home/delladmin/redis-6.0.7/src/deps/lua/src 下,先行编译。
但是在进入lua进行编译时报错:
0 1 2 |
$ make Please choose a platform: aix ansi bsd freebsd generic linux macosx mingw posix solaris |
查看你的系统平台名称是否在支持的列表中(肯定不在里面,如果在里面就不会有这样的提示了),如果存在则继续运行make PLATFORM命令,否则按照lua的INSTALL说明我们可以选择运行make generic命令(PS:我这里是针对linux编译,即make linux)。一般情况下编译都是成功的。
0 |
$ make generic |
编译成功。
报错 /bin/sh: cc: command not found
使用MinGW编译Redis时,提示:
0 |
/bin/sh: cc: command not found |
首先确认一下,上否安装了以下资源
0 |
gcc gcc-c++ libstdc++-devel |
如果确实安装了,还是出现上面的报错,那就在要编译的项目根目录找到 Makefile 文件,在此文件最顶部添加代码:
0 1 2 |
ifneq ($(CC), gcc) CC=gcc endif |
注:这个报错的原因就是没有申明变量 CC ,在这里申明一下就好了。
Makefile常用语法实例
Makefile常用语法实例,Makefile语法
一、Makefile基本格式:
make所看到的第一项规则会被当做默认规则使用。
一个规则可分成三个部分:
目标:依赖1 依赖2。。。
命令
注意:命令前必须使用有一个制表符(<TAB>)。 Continue reading
c语言工程下的.c文件.h文件.o文件.so文件.a文件 可执行文件 gcc使用
linux下c语言工程下的.c文件.h文件.o文件.so文件.a文件 可执行文件 gcc使用:
c文件:主要每个模块的原代码都在c文件中。
h文件:每个c文件都跟着一个h文件,h文件的作用是放着c文件中函数的声明,结构体的定义,宏的定义等。
o文件:目标文件。每个文件经过编译都会形成一个目标文件(二进制文件),多个目标文件链接后才能形成可执行文件。
o文件如何形成: gcc -c a.c
可执行文件:
不论是c文件还是o文件,都是无法执行的,最终还要生成可执行的文件。
gcc a.c b.c c.c -o run 将c文件编译后链接,生成可执行文件
gcc a.o b.o c.o -o run 将目标文件链接为可执行文件
Makefile选项 CFLAGS LDFLAGS
Makefile选项 CFLAGS和LDFLAGS
makefile内嵌隐含规则的命令中,所使用的变量都是预定义的变量。我们将这些变量称为“隐含变量”。这些变量允许对它进行修改:在Makefile中、通过命令行参数或者设置系统环境变量的方式来对它进行重定义。无论是用那种方式,只要make在运行时它的定义有效,make的隐含规则都会使用这些变量。 Continue reading