获取QQ好友列表的方法确实不多,3GQQ是一种办法,不过最简单的就是QQ邮箱获取了,这里有用了这种方式。QQ邮箱如果使用模拟登陆的话,又实在太麻烦,采取折中的方式,首先登陆,然后使用COOKIE模拟。
QQ邮箱可以发现又两个主要信息,其一为地址栏的地址,包含SID等。其二就是为COOKIE信息,可以在网络状况查询中很直观的获取。接下来使用PHP类获取。
<?php
/**
* QQ 好友列表获取类
* 使用方式:
*
* $qg = new Get_QQ_List();
* $ql->setUrl("https://mail.qq.com/c****");
* $ql->setCookie("tui_loginuin=2*************");
* $ql->dump();
*
* 使用脚本方式运行,php get_qq_list.php > E:\qq.html
* 执行HTML页面后,JS解析出一个表格,复制到EXECL中后可进行更复杂的操作
*
* Class Get_QQ_List
*/
class Get_QQ_List
{
/**
* @var string 用户SID
*/
private $sid;
/**
* @var string 引用页
*/
private $referer;
/**
* @var resource CURL句柄
*/
private $ch;
/**
* @var string COOKIE 字符串
*/
private $cookie;
function __construct()
{
$this->ch = curl_init();
//禁止验证SSL信息
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, FALSE);
}
/**
* 设置访问网址,和来路域名,即访问QQ邮箱跳转后的页面
* @param $url string
* @throws Exception
*/
public function setUrl($url)
{
$this->referer = $url;
preg_match_all("/sid=(.*)&/", $url, $matches);
if(isset($matches[1][0]))
{
$this->sid = $matches[1][0];
}else
{
throw new Exception("无法解析SID");
}
}
/**
* 设置从浏览器获取来的COOKIE信息
* @param $cookie string
*/
public function setCookie($cookie)
{
$this->cookie = $cookie;
}
/**
* 设置相应的头信息
*/
private function setHeader()
{
curl_setopt($this->ch, CURLOPT_URL, "https://set2.mail.qq.com/cgi-bin/laddr_list?sid=" . $this->sid . "&operate=view&t=contact&view=normal&loc=frame_html,,,23");
curl_setopt($this->ch, CURLOPT_COOKIE, $this->cookie);
curl_setopt($this->ch, CURLOPT_HEADER, 0);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->ch, CURLOPT_REFERER, $this->referer);
curl_setopt($this->ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36");
}
/**
* 开始输出信息
* @throws Exception
*/
public function dump()
{
if(empty($this->cookie) || empty($this->referer) || empty($this->sid))
{
throw new Exception("信息设置不全");
}
$this->setHeader();
$data = curl_exec($this->ch);
if($data === FALSE)
{
$this->error();
}
$list = $this->parse_group($data);
$rt = "";
foreach($list as $v)
{
$rt .= $this->get_page($v);
}
curl_close($this->ch);
echo $this->parse_file($rt);
}
/**
* 获取单独的列表页面
* @param $url
* @return string
*/
private function get_page($url)
{
curl_setopt($this->ch, CURLOPT_URL, "https://set2.mail.qq.com" . $url);
$data = curl_exec($this->ch);
if($data === FALSE)
{
$this->error();
}
return $data . "\n\n\n\n";
}
/**
* 解析页面文件
* @param $c
* @return string
*/
private function parse_file($c)
{
//$c = file_get_contents($c);
$c = explode("\n", $c);
$ss = "var goListData = ";
$obj = [];
foreach($c as &$v)
{
if(strpos($v, $ss) === 0)
{
$obj[] = substr($v, strlen($ss), -1);
}
$v = NULL;
}
$data = 'var data = [' . implode(",\n", $obj) . '];';
$data = mb_convert_encoding($data, 'UTF-8', 'GBK'); //转换内容编码为UTF-8
$info = <<<HTMLDATA
<html>
<head>
<title>QQ联系人</title>
<meta charset="utf-8">
</head>
<body>
<script>
{$data}
document.write("<table><thead><tr><td>名字</td><td>QQ</td><td>昵称</td><td>分组</td></tr></thead>");
for (var obj in data) {
for (var info in data[obj]) {
for (var ddd in data[obj][info]) {
var one = data[obj][info][ddd];
var nickname = '';
var qq = one['oEmail'][0]['sVal'].split('@');
qq = qq[0];
if (typeof one['oCustom'] != 'undefined' && typeof one['oCustom'][0] != 'undefined' && typeof one['oCustom'][0]['sVal'] != 'undefined') {
nickname = one['oCustom'][0]['sVal'];
} else {
nickname = one['oName'][0]['sVal'];
}
document.write("<tr><td>" + one['oName'][0]['sVal'] + "</td><td>" +
qq + "</td><td>" + nickname + "</td><td>" + one['oGroup'][0]['sName'] + "</td></tr>");
}
}
}
document.write("</table>");
</script>
</body>
</html>
HTMLDATA;
return $info; //返回一个HTML解析的页面
}
/**
* 分组列表解析
* @param $data
* @return array
*/
private function parse_group($data)
{
$i = strpos($data, "navlist_min navlist_qq");
$j = strpos($data, "panel_info settingtable qqshowbd");
$data = substr($data, $i, $j - $i);
preg_match_all('/<li class="fs"><a href="(.*?)"><span ui-type="grouptitle">/', $data, $matches);
if(isset($matches[1][0]))
{
return $matches[1];
}
return [];
}
/**
* 错误信息输出
*/
private function error()
{
echo "ERROR:" . curl_error($this->ch);
exit;
}
}
/**
* QQ 好友列表获取类
* 使用方式:
*
* $qg = new Get_QQ_List();
* $ql->setUrl("https://mail.qq.com/c****");
* $ql->setCookie("tui_loginuin=2*************");
* $ql->dump();
*
* 使用脚本方式运行,php get_qq_list.php > E:\qq.html
* 执行HTML页面后,JS解析出一个表格,复制到EXECL中后可进行更复杂的操作
*
* Class Get_QQ_List
*/
class Get_QQ_List
{
/**
* @var string 用户SID
*/
private $sid;
/**
* @var string 引用页
*/
private $referer;
/**
* @var resource CURL句柄
*/
private $ch;
/**
* @var string COOKIE 字符串
*/
private $cookie;
function __construct()
{
$this->ch = curl_init();
//禁止验证SSL信息
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, FALSE);
}
/**
* 设置访问网址,和来路域名,即访问QQ邮箱跳转后的页面
* @param $url string
* @throws Exception
*/
public function setUrl($url)
{
$this->referer = $url;
preg_match_all("/sid=(.*)&/", $url, $matches);
if(isset($matches[1][0]))
{
$this->sid = $matches[1][0];
}else
{
throw new Exception("无法解析SID");
}
}
/**
* 设置从浏览器获取来的COOKIE信息
* @param $cookie string
*/
public function setCookie($cookie)
{
$this->cookie = $cookie;
}
/**
* 设置相应的头信息
*/
private function setHeader()
{
curl_setopt($this->ch, CURLOPT_URL, "https://set2.mail.qq.com/cgi-bin/laddr_list?sid=" . $this->sid . "&operate=view&t=contact&view=normal&loc=frame_html,,,23");
curl_setopt($this->ch, CURLOPT_COOKIE, $this->cookie);
curl_setopt($this->ch, CURLOPT_HEADER, 0);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->ch, CURLOPT_REFERER, $this->referer);
curl_setopt($this->ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36");
}
/**
* 开始输出信息
* @throws Exception
*/
public function dump()
{
if(empty($this->cookie) || empty($this->referer) || empty($this->sid))
{
throw new Exception("信息设置不全");
}
$this->setHeader();
$data = curl_exec($this->ch);
if($data === FALSE)
{
$this->error();
}
$list = $this->parse_group($data);
$rt = "";
foreach($list as $v)
{
$rt .= $this->get_page($v);
}
curl_close($this->ch);
echo $this->parse_file($rt);
}
/**
* 获取单独的列表页面
* @param $url
* @return string
*/
private function get_page($url)
{
curl_setopt($this->ch, CURLOPT_URL, "https://set2.mail.qq.com" . $url);
$data = curl_exec($this->ch);
if($data === FALSE)
{
$this->error();
}
return $data . "\n\n\n\n";
}
/**
* 解析页面文件
* @param $c
* @return string
*/
private function parse_file($c)
{
//$c = file_get_contents($c);
$c = explode("\n", $c);
$ss = "var goListData = ";
$obj = [];
foreach($c as &$v)
{
if(strpos($v, $ss) === 0)
{
$obj[] = substr($v, strlen($ss), -1);
}
$v = NULL;
}
$data = 'var data = [' . implode(",\n", $obj) . '];';
$data = mb_convert_encoding($data, 'UTF-8', 'GBK'); //转换内容编码为UTF-8
$info = <<<HTMLDATA
<html>
<head>
<title>QQ联系人</title>
<meta charset="utf-8">
</head>
<body>
<script>
{$data}
document.write("<table><thead><tr><td>名字</td><td>QQ</td><td>昵称</td><td>分组</td></tr></thead>");
for (var obj in data) {
for (var info in data[obj]) {
for (var ddd in data[obj][info]) {
var one = data[obj][info][ddd];
var nickname = '';
var qq = one['oEmail'][0]['sVal'].split('@');
qq = qq[0];
if (typeof one['oCustom'] != 'undefined' && typeof one['oCustom'][0] != 'undefined' && typeof one['oCustom'][0]['sVal'] != 'undefined') {
nickname = one['oCustom'][0]['sVal'];
} else {
nickname = one['oName'][0]['sVal'];
}
document.write("<tr><td>" + one['oName'][0]['sVal'] + "</td><td>" +
qq + "</td><td>" + nickname + "</td><td>" + one['oGroup'][0]['sName'] + "</td></tr>");
}
}
}
document.write("</table>");
</script>
</body>
</html>
HTMLDATA;
return $info; //返回一个HTML解析的页面
}
/**
* 分组列表解析
* @param $data
* @return array
*/
private function parse_group($data)
{
$i = strpos($data, "navlist_min navlist_qq");
$j = strpos($data, "panel_info settingtable qqshowbd");
$data = substr($data, $i, $j - $i);
preg_match_all('/<li class="fs"><a href="(.*?)"><span ui-type="grouptitle">/', $data, $matches);
if(isset($matches[1][0]))
{
return $matches[1];
}
return [];
}
/**
* 错误信息输出
*/
private function error()
{
echo "ERROR:" . curl_error($this->ch);
exit;
}
}
运行过程中必须保持浏览器不关闭,否则会导致COOKIE过期,而无法获取任何信息。导出的列表并没有解析,原始数据为javascript变量,直接使用浏览器去解析可以很方便。因此导出一个HTML文件,然后生成一个表格。利用生成的表格就行了。导出的数据有四项,包含QQ号、QQ备注、QQ昵称、QQ好友分组。
不会用。。
用途也不大!总有其他办法
做成油猴脚本不更方便
不错,收藏先,以后可能会用到
挺厉害啊
这为啥要导出呢?
不错
何必这么麻烦
有简单的办法么???
转为aauto代码可行不?
应该是可以的,只是我没那份心情转
可以用来干么
还没怎么想好,不过确实有时候用得着
这么多 ???为啥