爬虫(二)实现qq空间的自动评论和自动点赞

会抓个网页总感觉还不够,平时在空间里经常会遇到秒赞或者是秒评论的,现在也可以自己用爬虫在qq空间得到需要的信息,再向特定的url发送http请求就可以做到自动评论和点赞了,使用的cookie登录,好像有点low,尝试过账号密码登陆,但没成功,那就将就着吧,以后再来研究

1.1   首先先用cookie登录qq空间,抓取到页面的内容,用pc端打开自己的qq空间,按F12进入开发者模式,可以看到自己的cookie,把这个复制下来

然后就用cookie登陆抓取到自己qq空间的内容

$qq = "这里写自己的qq";
$cookie = "这里复制cookie";
$ch = curl_init();
$url = "https://user.qzone.qq.com/".$qq;

//设置访问的URL
curl_setopt($ch, CURLOPT_URL, $url);

//设置http头
$http_header = array(
    	"User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:61.0) Gecko/20100101 Firefox/61.0",
    	"Accepted-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    	"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    	"Cookie: $cookie" );

//设置HTTP报文头的用户信息
curl_setopt($ch, CURLOPT_HTTPHEADER, $http_header);

//不需要响应报文头
curl_setopt($ch, CURLOPT_HEADER, FALSE);

//跳过https验证
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
    
//返回响应信息而不是直接输出
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

if (!$output = curl_exec($ch)) {
    echo "Curl Error:". curl_error($ch);
}
curl_close($ch);

得到的 $output就是自己得到的qq空间页面了

2.2   接着看下点赞所请求的url是啥,随便找个人点赞,发现

发现url前面那一段倒是容易理解,后面跟着的参数和 g_tkqzonetoken 那是啥,百度了下,才知道gtk是根据cookie里面的p_skey的值经过一个算法得到的,qzonetoken是每次登陆得到的一个值,在qq空间的网页中按F12,打开网页元素界面按ctrl+F输入qzonetoken ,查找qzonetoken,可以看到高亮部分

那就用正则匹配把他匹配出来就行了

if ($output){
preg_match('/window\.g_qzonetoken = \(function\(\)\{ try\{return "(.*?)";\} catch\(e\)/',$output, $matches2);
    $qzonetoken = $matches2[1];
}

那qzonetoken有了,接下来看看g_tk怎么得到,既然是根据cookie中的p_skey的值得到,那先把p_skey匹配出来

 preg_match('/p_skey=([^;^\']*)/', $http_header[3], $matches);
    $p_skey = $matches[1];

那算法百度一下

<?php
  function getGtk($skey){
    $hash = 5381;
    for($i=0;$i<strlen($skey);++$i){
      $hash += ($hash << 5) + utf8_uni($skey[$i]);
    }
    return $hash & 0x7fffffff;
  }
  function utf8_uni($u){
    switch(strlen($u)){
      case 1: return ord($u);
      case 2: $n = (ord($u[0]) & 0x3f) << 6;
      $n += ord($u[1]) & 0x3f;
      return $n;
      case 3: $n = (ord($u[0]) & 0x1f) << 12;
      $n += (ord($u[1]) & 0x3f) << 6;
      $n += ord($u[2]) & 0x3f;
      return $n;
      case 4: $n = (ord($u[0]) & 0x0f) << 18;
      $n += (ord($u[1]) & 0x3f) << 12;
      $n += (ord($u[2]) & 0x3f) << 6;
      $n += ord($u[3]) & 0x3f;
      return $n;
    }
  }
?>

把他存为gtk.php,放在同一目录下,然后得到g_tk的值就可以整合为

require('gtk.php');
preg_match('/p_skey=([^;^\']*)/', $http_header[3], $matches);
$p_skey = $matches[1];    
$gtk = getGTK($p_skey);

1.3  好咯现在url的参数没问题那就构建数据包发送过去就可以了,在qq里随便点个赞,看看开发者中心里的数据包都需要什么

qzreferrer那段其实到qq号那里就够了,

opuin是自己的qq,那unikey和curkey又是啥,再在网页中找unikey,

发现这是每条说说都跟着一个自己的unikey和curkey,这是拿来辨识是那条说说的,

那需要在匹配出qzonetoken的时候再把unikey给匹配出来

if ($output){
    //这里匹配出qzonetoken
    preg_match('/window\.g_qzonetoken = \(function\(\)\{ try\{return "(.*?)";\} catch\(e\)/',$output, $matches2);
    $qzonetoken = $matches2[1];

    //正则匹配出unikey和curkey,unikey是$key[1][n],,unikey就是与qq好友相关的说说信息
    $regex1 = '/data-unikey="(http[^"]*)"[^d]*data-curkey="([^"]*)"[^d]*data-clicklog=("like")[^h]*href="javascript:;"/';

	//得到的$key就是我们想要的
    preg_match_all($regex1, $output, $key);
}

1.4  接着就构建数据包发送点赞的http请求啦

//构建点赞所需的数据包
    for($i = 0; $i < count($key); $i++){
    	//时间为时间戳格式
    	$time = time();
    	$fid  = explode('/', $key[1][$i]);
    	//数据包
    	$data = array(
		"qzreferrer"	        =>	"https://user.qzone.qq.com/".$qq,
		"opuin"			=>	$qq,
		"unikey"		=>	$key[1][$i],
		"curkey"		=>	$key[2][$i],
		"from"			=>	"1",
		"appid"			=>	"311",
		"typeid"		=>	"0",
		"abstime"		=>	$time,
		"fid"		    =>	$fid[5],
		"active"		=>	"0",
		"fupdate"		=>	"1"
		);
       
    //使用curl发送数据包
	$ch2 = curl_init();

	//点赞请求的url
	$url2 = "https://user.qzone.qq.com/proxy/domain/w.qzone.qq.com/cgi-bin/likes/internal_dolike_app?g_tk=".$gtk.'&qzonetoken=.'$qzonetoken;
    curl_setopt($ch2, CURLOPT_URL, $url2);
	//请求HTTP报文头
	curl_setopt($ch2, CURLOPT_HTTPHEADER, $http_header);
	//不需要响应报文头
	curl_setopt($ch2, CURLOPT_HEADER, FALSE);
	//跳过https验证
	curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, FALSE); 
	curl_setopt($ch2, CURLOPT_SSL_VERIFYHOST, FALSE); 
	//返回响应信息而不是直接输出
    curl_setopt($ch2, CURLOPT_RETURNTRANSFER, TRUE);
	//设置post信息
	curl_setopt($ch2, CURLOPT_POST, TRUE);
	//改善数据格式
	curl_setopt($ch2, CURLOPT_POSTFIELDS, http_build_query($data));


	//开始执行
	if($output2 = curl_exec($ch2)){
		echo "点赞成功<br/>";
	}
	else{
		echo curl_error($ch2);
	}
	curl_close($ch2);
	
}

1.5  再在结尾加上就实现3秒自动刷新一次,自己服务器上进入这个文件就可以自动点赞新说说了

echo "系统当前时间戳为:".time();
//<!--JS 页面自动刷新 -->
echo "<script type=\"text/javascript\">";
echo "function fresh_page()";    
echo "{";
echo "window.location.reload();";
echo "}"; 
echo "setTimeout('fresh_page()',3000);";      
echo "</script>";

2.1  现在实行了自动点赞的功能了,接下来来做自动评论的功能了,本质上都是一样的,从页面中得到需要的参数信息,再构建数据包发送到特定的url就可以了,看下url

两个需要的参数刚刚都得到了

2.2看下数据包所需的数据

就只有这两个从网页需要正则匹配出来

所以就在匹配出qzonetoken,unikey的时候再把给这个匹配出来

整合如下

if ($output) {
    	//得到qzonetoken
    	preg_match('/window\.g_qzonetoken = \(function\(\)\{ try\{return "(.*?)";\} catch\(e\)/',$output, $matches2);
    	$qzonetoken = $matches2[1];

    //正则匹配出unikey和curkey,unikey是$key[1][n],,unikey就是与qq好友相关的说说信息
	$regex1 = '/data-unikey="(http[^"]*)"[^d]*data-curkey="([^"]*)"[^d]*data-clicklog=("like")[^h]*href="javascript:;"/';
	//得到的$unikey就是我们想要的
	preg_match_all($regex1, $output, $key);

	//匹配出需要的topicid以及qq号,得到的qq号是$matches[1][$i],topicid是$matches[1][$i].'_'.$matches[2][$i]
	preg_match_all('/data-topicid="(\w+)_(\w+__\w+)"/',$output, $comment_matches);
			
    }

2.3  构建评论所需要的数据包并发送

for($i = 0; $i < count($comment_matches[1]); $i++){
    	$time = time();
    	$data_comment = array(
    		'topicId' => $comment_matches[1][$i].'_'.$comment_matches[2][$i],
			'feedsType' => 100,  //这是说说的类型,是普通文字说说和配图说说
			'inCharset' => 'utf-8',
			'outCharset' => 'utf-8',
			'plat' => 'qzone',
			'source' => 'ic',
			'hostUin' => $comment_matches[1][$i],
			'isSignIn' => '',
			'platformid' => 52,
			'uin' => $qq,
			'format' => 'fs',
			'ref' => 'feeds',
			'content' => $comment, //这里的comment就是自动评论的内容,要自己设定
			'richval' => '',
			'richtype' => '',
			'private' => 0,
			'paramstr' => 1,
			'qzreferrer' => 'https://user.qzone.qq.com/'.$qq.'/infocenter',
		);
		
	
		//使用curl发送数据包
	    $ch3 = curl_init();
	    //点赞的url格式
		$url3 = "https://user.qzone.qq.com/proxy/domain/taotao.qzone.qq.com/cgi-bin/emotion_cgi_re_feeds?qzonetoken=".$qzonetoken."&g_tk="$gtk;
		//echo $url2;
		curl_setopt($ch3, CURLOPT_URL, $url3);
	    //设置测试用的HTTP报文头的用户信息
	    curl_setopt($ch3, CURLOPT_HTTPHEADER, $http_header);
	    //不需要报文头
	    curl_setopt($ch3, CURLOPT_HEADER, FALSE);
	    //跳过https验证
	    curl_setopt($ch3, CURLOPT_SSL_VERIFYPEER, FALSE); 
		curl_setopt($ch3, CURLOPT_SSL_VERIFYHOST, FALSE); 
		//返回响应信息而不是直接输出
    	curl_setopt($ch3, CURLOPT_RETURNTRANSFER, TRUE);
		//设置post信息
		curl_setopt($ch3, CURLOPT_POST, TRUE);
		//数据包格式
		curl_setopt($ch3, CURLOPT_POSTFIELDS, http_build_query($data_comment));

		//开始执行
		if($output3 = curl_exec($ch3)){
			echo "评论成功<br/>";
		}
		else{
			echo curl_error($ch3);
		}
		curl_close($ch3);
	}

好啦,现在完成了自动点赞自动评论的功能现在把代码整合在一起

<?php

#################################这里使用cookie登录获得点赞post数据包所需的内容####################################

    require("gtk.php");
    $qq = "这里写自己的qq";
    $comment = "自动评论的内容";
    $cookie = "这里复制cookie";
	$ch = curl_init();
	$url = "https://user.qzone.qq.com/".$qq;
    //设置访问的URL
    curl_setopt($ch, CURLOPT_URL, $url);
    //设置http头
    $http_header = array(
    		"User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:61.0) Gecko/20100101 Firefox/61.0",
    		"Accepted-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    		"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    		"Cookie: $cookie" );
    //设置测试用的HTTP报文头的用户信息
    curl_setopt($ch, CURLOPT_HTTPHEADER, $http_header);

    //不需要报文头
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    //跳过https验证
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
    //返回响应信息而不是直接输出
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

   if (!$output = curl_exec($ch)) {
    	echo "Curl Error:". curl_error($ch);
    }
    curl_close($ch);
    //echo $output;

    //点赞post的数据包里有unikey和
    if ($output) {
    	//得到qzonetoken
    	preg_match('/window\.g_qzonetoken = \(function\(\)\{ try\{return "(.*?)";\} catch\(e\)/',$output, $matches2);
    	$qzonetoken = $matches2[1];

    	//正则匹配出unikey和curkey,unikey是$key[1][n],,unikey就是与qq好友相关的说说信息
		$regex1 = '/data-unikey="(http[^"]*)"[^d]*data-curkey="([^"]*)"[^d]*data-clicklog=("like")[^h]*href="javascript:;"/';
		//得到的$unikey就是我们想要的
		preg_match_all($regex1, $output, $key);

		//匹配出需要的topicid以及qq号,得到的qq号是$matches[1][$i],topicid是$matches[1][$i].'_'.$matches[2][$i]
		preg_match_all('/data-topicid="(\w+)_(\w+__\w+)"/',$output, $comment_matches);
			
    }
   
    //得到构建点赞请求的url中g_tk和qzonetoken的值,gtk是根据cookie中的p_skey经过特殊的算法得到,qzonetoken直接匹配得到
#################################这里使用cookie登录获得点赞post数据包所需的内容结束################################
    //得到pskey
    preg_match('/p_skey=([^;^\']*)/', $http_header[3], $matches);
    $gtk = getGTK($matches[1]);
    
    //echo $gtk.'<br/>'.$qzonetoken;

#############################################这里开始完成自动点赞的功能##########################################

    //构建点赞所需的数据包
    for($i = 0; $i < count($key); $i++){
    	//时间为时间戳格式
    	$time = time();
    	$fid  = explode('/', $key[1][$i]);
    	//数据包
    	$data = array(
		"qzreferrer"	        =>	"https://user.qzone.qq.com/".$qq,
		"opuin"			=>	$qq,
		"unikey"		=>	$key[1][$i],
		"curkey"		=>	$key[2][$i],
		"from"			=>	"1",
		"appid"			=>	"311",
		"typeid"		=>	"0",
		"abstime"		=>	$time,
		"fid"		    =>	$fid[5],
		"active"		=>	"0",
		"fupdate"		=>	"1"
		);
    	

		//使用curl发送数据包
	    $ch2 = curl_init();
	    //点赞的url格式
		$url2 = "https://user.qzone.qq.com/proxy/domain/w.qzone.qq.com/cgi-bin/likes/internal_dolike_app?g_tk=".$gtk."qzonetoken=".$qzonetoken;
		
		curl_setopt($ch2, CURLOPT_URL, $url2);
	    //设置测试用的HTTP报文头的用户信息
	    curl_setopt($ch2, CURLOPT_HTTPHEADER, $http_header);
	    //不需要报文头
	    curl_setopt($ch2, CURLOPT_HEADER, FALSE);
	    //跳过https验证
	    curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, FALSE); 
		curl_setopt($ch2, CURLOPT_SSL_VERIFYHOST, FALSE); 
		//返回响应信息而不是直接输出
    	curl_setopt($ch2, CURLOPT_RETURNTRANSFER, TRUE);
		//设置post信息
		curl_setopt($ch2, CURLOPT_POST, TRUE);
		//数据包格式
		curl_setopt($ch2, CURLOPT_POSTFIELDS, http_build_query($data));


		//开始执行
		if($output2 = curl_exec($ch2)){
			echo "点赞成功<br/>";
		}
		else{
			echo curl_error($ch2);
		}
		curl_close($ch2);

	
	}

#############################################这里开始完成自动评论的功能##########################################
	for($i = 0; $i < count($comment_matches[1]); $i++){
    	$time = time();
    	$data_comment = array(
    		'topicId' => $comment_matches[1][$i].'_'.$comment_matches[2][$i],
			'feedsType' => 100,  //这是说说的类型,是普通文字说说和配图说说
			'inCharset' => 'utf-8',
			'outCharset' => 'utf-8',
			'plat' => 'qzone',
			'source' => 'ic',
			'hostUin' => $comment_matches[1][$i],
			'isSignIn' => '',
			'platformid' => 52,
			'uin' => $qq,
			'format' => 'fs',
			'ref' => 'feeds',
			'content' => $comment,
			'richval' => '',
			'richtype' => '',
			'private' => 0,
			'paramstr' => 1,
			'qzreferrer' => 'https://user.qzone.qq.com/'.$qq.'/infocenter',
		);
		
	
		//使用curl发送数据包
	    $ch3 = curl_init();
	    //点赞的url格式
		$url3 = "https://user.qzone.qq.com/proxy/domain/taotao.qzone.qq.com/cgi-bin/emotion_cgi_re_feeds?qzonetoken=".$qzonetoken."&g_tk=".$gtk;
		//echo $url2;
		curl_setopt($ch3, CURLOPT_URL, $url3);
	    //设置测试用的HTTP报文头的用户信息
	    curl_setopt($ch3, CURLOPT_HTTPHEADER, $http_header);
	    //不需要报文头
	    curl_setopt($ch3, CURLOPT_HEADER, FALSE);
	    //跳过https验证
	    curl_setopt($ch3, CURLOPT_SSL_VERIFYPEER, FALSE); 
	    curl_setopt($ch3, CURLOPT_SSL_VERIFYHOST, FALSE); 
		//返回响应信息而不是直接输出
    	curl_setopt($ch3, CURLOPT_RETURNTRANSFER, TRUE);
		//设置post信息
		curl_setopt($ch3, CURLOPT_POST, TRUE);
		//数据包格式
		curl_setopt($ch3, CURLOPT_POSTFIELDS, http_build_query($data_comment));

		//开始执行
		if($output3 = curl_exec($ch3)){
			echo "评论成功<br/>";
		}
		else{
			echo curl_error($ch3);
		}
		curl_close($ch3);
	}
	echo "系统当前时间戳为:".time();
	//<!--JS 页面自动刷新 -->
	echo "<script type=\"text/javascript\">";
	echo "function fresh_page()";    
	echo "{";
	echo "window.location.reload();";
	echo "}"; 
	echo "setTimeout('fresh_page()',3000);";      
	echo "</script>";
    
?>

写的有点乱,如果哪里不对希望能指出来以改正

有兴趣的可以把这个包装成类加深理解,也因为自己有点懒,还是第一次写这么长的博客

猜你喜欢

转载自blog.csdn.net/qq_40691208/article/details/81167019