Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation
This project
Loading...
Sign in
hfpp2012
/
vbot
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 36830edf
authored
Dec 08, 2016
by
hanccc
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
增加登录方法
1 parent
174552dd
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
552 additions
and
9 deletions
composer.json
composer.lock
src/Robot.php
test/test.php
composer.json
View file @
36830ed
...
@@ -9,7 +9,11 @@
...
@@ -9,7 +9,11 @@
}
}
],
],
"require"
:
{
"require"
:
{
"guzzlehttp/guzzle"
:
"^6.2"
"guzzlehttp/guzzle"
:
"^6.2"
,
"querypath/QueryPath"
:
"^3.0"
,
"symfony/dom-crawler"
:
"^3.2"
,
"endroid/qrcode"
:
"^1.7"
,
"symfony/css-selector"
:
"^3.2"
},
},
"autoload"
:
{
"autoload"
:
{
"psr-4"
:
{
"psr-4"
:
{
...
...
composer.lock
View file @
36830ed
...
@@ -4,10 +4,61 @@
...
@@ -4,10 +4,61 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
"This file is @generated automatically"
],
],
"hash": "
f5c4e1f28cd3459bcceea817aeb70175
",
"hash": "
5d864dbf0e5d931155a639d3550d8797
",
"content-hash": "
a5cd8cbd0f2e29cd0e02a802ac2f7b7e
",
"content-hash": "
43e84ce436c790f7670e8caa6fe63079
",
"packages": [
"packages": [
{
{
"name": "endroid/qrcode",
"version": "1.7.4",
"source": {
"type": "git",
"url": "https://github.com/endroid/QrCode.git",
"reference": "ba35ed8f0686bc4ec82874752778ccb427261a41"
},
"dist": {
"type": "zip",
"url": "https://packagist.phpcomposer.com/files/endroid/QrCode/ba35ed8f0686bc4ec82874752778ccb427261a41.zip",
"reference": "ba35ed8f0686bc4ec82874752778ccb427261a41",
"shasum": ""
},
"require": {
"ext-gd": "*",
"php": ">=5.3.0",
"symfony/options-resolver": "^2.3|^3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Endroid\\QrCode\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jeroen van den Enden",
"email": "info@endroid.nl",
"homepage": "http://endroid.nl/"
}
],
"description": "Endroid QR Code",
"homepage": "https://github.com/endroid/QrCode",
"keywords": [
"code",
"endroid",
"qr",
"qrcode"
],
"time": "2016-07-26 09:39:07"
},
{
"name": "guzzlehttp/guzzle",
"name": "guzzlehttp/guzzle",
"version": "6.2.2",
"version": "6.2.2",
"source": {
"source": {
...
@@ -179,6 +230,71 @@
...
@@ -179,6 +230,71 @@
"time": "2016-06-24 23:00:38"
"time": "2016-06-24 23:00:38"
},
},
{
{
"name": "masterminds/html5",
"version": "2.2.2",
"source": {
"type": "git",
"url": "https://github.com/Masterminds/html5-php.git",
"reference": "7866e93dcf0245de22378414e0c2c7350abc45af"
},
"dist": {
"type": "zip",
"url": "https://packagist.phpcomposer.com/files/Masterminds/html5-php/7866e93dcf0245de22378414e0c2c7350abc45af.zip",
"reference": "7866e93dcf0245de22378414e0c2c7350abc45af",
"shasum": ""
},
"require": {
"ext-libxml": "*",
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.*",
"sami/sami": "~2.0",
"satooshi/php-coveralls": "1.0.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.2-dev"
}
},
"autoload": {
"psr-4": {
"Masterminds\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Matt Butcher",
"email": "technosophos@gmail.com"
},
{
"name": "Asmir Mustafic",
"email": "goetas@gmail.com"
},
{
"name": "Matt Farina",
"email": "matt@mattfarina.com"
}
],
"description": "An HTML5 parser and serializer.",
"homepage": "http://masterminds.github.io/html5-php",
"keywords": [
"HTML5",
"dom",
"html",
"parser",
"querypath",
"serializer",
"xml"
],
"time": "2016-09-22 11:01:11"
},
{
"name": "psr/http-message",
"name": "psr/http-message",
"version": "1.0.1",
"version": "1.0.1",
"source": {
"source": {
...
@@ -227,6 +343,270 @@
...
@@ -227,6 +343,270 @@
"response"
"response"
],
],
"time": "2016-08-06 14:39:51"
"time": "2016-08-06 14:39:51"
},
{
"name": "querypath/querypath",
"version": "3.0.5",
"source": {
"type": "git",
"url": "https://github.com/technosophos/querypath.git",
"reference": "6b8e2395fac61fac25bbe962f94def556cb85f7d"
},
"dist": {
"type": "zip",
"url": "https://packagist.phpcomposer.com/files/technosophos/querypath/6b8e2395fac61fac25bbe962f94def556cb85f7d.zip",
"reference": "6b8e2395fac61fac25bbe962f94def556cb85f7d",
"shasum": ""
},
"require": {
"masterminds/html5": "2.*",
"php": ">=5.3.0"
},
"type": "library",
"autoload": {
"psr-0": {
"QueryPath": "src/"
},
"files": [
"src/qp_functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "HTML/XML querying (CSS 4 or XPath) and processing (like jQuery)",
"homepage": "https://github.com/technosophos/querypath",
"keywords": [
"css",
"html",
"jquery",
"xml",
"xslt"
],
"time": "2016-08-01 22:40:30"
},
{
"name": "symfony/css-selector",
"version": "v3.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "e1241f275814827c411d922ba8e64cf2a00b2994"
},
"dist": {
"type": "zip",
"url": "https://packagist.phpcomposer.com/files/symfony/css-selector/e1241f275814827c411d922ba8e64cf2a00b2994.zip",
"reference": "e1241f275814827c411d922ba8e64cf2a00b2994",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\CssSelector\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2016-11-03 08:11:03"
},
{
"name": "symfony/dom-crawler",
"version": "v3.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "c6b6111f5aae7c58698cdc10220785627ac44a2c"
},
"dist": {
"type": "zip",
"url": "https://packagist.phpcomposer.com/files/symfony/dom-crawler/c6b6111f5aae7c58698cdc10220785627ac44a2c.zip",
"reference": "c6b6111f5aae7c58698cdc10220785627ac44a2c",
"shasum": ""
},
"require": {
"php": ">=5.5.9",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"symfony/css-selector": "~2.8|~3.0"
},
"suggest": {
"symfony/css-selector": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\DomCrawler\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2016-11-25 12:32:42"
},
{
"name": "symfony/options-resolver",
"version": "v3.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
"reference": "45940bcad6388b3b6058107eca67ced738d205bb"
},
"dist": {
"type": "zip",
"url": "https://packagist.phpcomposer.com/files/symfony/options-resolver/45940bcad6388b3b6058107eca67ced738d205bb.zip",
"reference": "45940bcad6388b3b6058107eca67ced738d205bb",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\OptionsResolver\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony OptionsResolver Component",
"homepage": "https://symfony.com",
"keywords": [
"config",
"configuration",
"options"
],
"time": "2016-05-13 18:13:23"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
},
"dist": {
"type": "zip",
"url": "https://packagist.phpcomposer.com/files/symfony/polyfill-mbstring/e79d363049d1c2128f133a2667e4f4190904f7f4.zip",
"reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"time": "2016-11-14 01:06:16"
}
}
],
],
"packages-dev": [],
"packages-dev": [],
...
...
src/Robot.php
View file @
36830ed
...
@@ -9,24 +9,73 @@
...
@@ -9,24 +9,73 @@
namespace
Hanson\Robot
;
namespace
Hanson\Robot
;
use
Endroid\QrCode\QrCode
;
use
GuzzleHttp\Client
;
use
GuzzleHttp\Client
;
use
Symfony\Component\DomCrawler\Crawler
;
class
Robot
class
Robot
{
{
private
$client
;
private
$client
;
public
$tmpPath
;
private
$uuid
;
private
$uuid
;
private
$baseUri
;
private
$baseUri
=
'https://wx2.qq.com/cgi-bin/mmwebwx-bin'
;
private
$baseHost
;
private
$baseHost
=
'wx2.qq.com'
;
private
$redirectUri
;
private
$redirectUri
;
public
function
__construct
()
private
$skey
;
private
$sid
;
private
$uin
;
private
$passTicket
;
private
$deviceId
;
private
$baseRequest
;
public
function
__construct
(
Array
$option
=
[])
{
{
$this
->
client
=
new
Client
();
$this
->
client
=
new
Client
();
$this
->
handleOption
(
$option
);
}
/**
* 处理option
*
* @param $option
*/
private
function
handleOption
(
$option
)
{
$this
->
tmpPath
=
$option
[
'tmp'
]
??
sys_get_temp_dir
();
}
public
function
run
()
{
$this
->
getUuid
();
$this
->
generateQrCode
();
$this
->
log
(
'[INFO] 请用微信扫码'
);
if
(
$this
->
waitForLogin
()
!==
200
){
die
(
'[ERROR] 微信登录失败'
);
}
if
(
!
$this
->
login
()){
die
(
'[ERROR] 登录失败'
);
}
$this
->
log
(
'[INFO] 登录成功'
);
$this
->
init
();
}
}
/**
/**
...
@@ -53,6 +102,115 @@ class Robot
...
@@ -53,6 +102,115 @@ class Robot
$this
->
uuid
=
$matches
[
2
];
$this
->
uuid
=
$matches
[
2
];
}
}
/**
* 生成登录二维码
*/
public
function
generateQrCode
()
{
$url
=
'https://login.weixin.qq.com/l/'
.
$this
->
uuid
;
$qrCode
=
new
QrCode
(
$url
);
$file
=
$this
->
tmpPath
.
'login_qr_code.png'
;
$qrCode
->
save
(
$file
);
if
(
strtoupper
(
substr
(
PHP_OS
,
0
,
3
))
===
'WIN'
)
{
system
(
$file
);
}
}
/**
* 等待登录
*
* @return int
*/
public
function
waitForLogin
()
:
int
{
$urlTemplate
=
'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?tip=%s&uuid=%s&_=%s'
;
$retryTime
=
10
;
$tip
=
1
;
$code
=
0
;
while
(
$retryTime
>
0
){
$url
=
sprintf
(
$urlTemplate
,
$tip
,
$this
->
uuid
,
time
());
$content
=
$this
->
client
->
get
(
$url
)
->
getBody
()
->
getContents
();
preg_match
(
'/window.code=(\d+);/'
,
$content
,
$matches
);
$code
=
$matches
[
1
];
switch
(
$code
){
case
'201'
:
$this
->
log
(
'[INFO] 请点击确认进行登录'
);
$tip
=
0
;
break
;
case
'200'
:
preg_match
(
'/window.redirect_uri="(\S+?)";/'
,
$content
,
$matches
);
$this
->
redirectUri
=
$matches
[
1
]
.
'&fun=new'
;
return
$code
;
case
'408'
:
$this
->
log
(
'[ERROR] 微信登录超时。将在 1 秒后重试'
);
$tip
=
1
;
$retryTime
-=
1
;
sleep
(
1
);
break
;
default
:
$this
->
log
(
'[ERROR] 微信登录异常。异常码:%s 。1 秒后重试'
,
$code
);
$tip
=
1
;
$retryTime
-=
1
;
sleep
(
1
);
break
;
}
}
return
$code
;
}
public
function
login
()
{
$content
=
$this
->
client
->
get
(
$this
->
redirectUri
)
->
getBody
()
->
getContents
();
$crawler
=
new
Crawler
(
$content
);
$this
->
skey
=
$crawler
->
filter
(
'error skey'
)
->
text
();
$this
->
sid
=
$crawler
->
filter
(
'error wxsid'
)
->
text
();
$this
->
uin
=
$crawler
->
filter
(
'error wxuin'
)
->
text
();
$this
->
passTicket
=
$crawler
->
filter
(
'error pass_ticket'
)
->
text
();
if
(
in_array
(
''
,
[
$this
->
skey
,
$this
->
sid
,
$this
->
uin
,
$this
->
passTicket
])){
return
false
;
}
$this
->
deviceId
=
'e'
.
strval
(
random_int
(
100000000000000
,
999999999999999
));
$this
->
baseRequest
=
[
'Uin'
=>
$this
->
uin
,
'Sid'
=>
$this
->
sid
,
'Skey'
=>
$this
->
skey
,
'DeviceID'
=>
$this
->
deviceId
];
return
true
;
}
public
function
init
()
{
$url
=
sprintf
(
$this
->
baseUri
.
'/webwxinit?r=%i&lang=en_US&pass_ticket=%s'
,
time
(),
$this
->
passTicket
);
$content
=
$this
->
client
->
post
(
$url
,
[
'query'
=>
[
'BaseRequest'
=>
json_encode
(
$this
->
baseRequest
)
]
])
->
getBody
()
->
getContents
();
print_r
(
$content
);
}
private
function
log
(
$msg
,
...
$args
)
{
echo
sprintf
(
$msg
.
PHP_EOL
,
$args
);
}
public
function
__get
(
$value
)
public
function
__get
(
$value
)
{
{
return
$this
->
$value
;
return
$this
->
$value
;
...
...
test/test.php
View file @
36830ed
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
require_once
__DIR__
.
'./../vendor/autoload.php'
;
require_once
__DIR__
.
'./../vendor/autoload.php'
;
$robot
=
new
\Hanson\Robot\Robot
();
$robot
->
getUuid
();
echo
$robot
->
uuid
;
\ No newline at end of file
\ No newline at end of file
$robot
=
new
\Hanson\Robot\Robot
([
'tmp'
=>
realpath
(
'./tmp'
)
.
'/'
]);
echo
$robot
->
run
();
echo
'finish'
;
//
echo
$robot
->
uuid
;
\ No newline at end of file
\ No newline at end of file
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment