Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
py12306
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
python
py12306
Commits
0e287096
Commit
0e287096
authored
Jan 07, 2019
by
Jalin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加乘客检测
parent
afe2962b
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
193 additions
and
24 deletions
+193
-24
main.py
main.py
+5
-2
config.py
py12306/config.py
+14
-0
MemberInvalidException.py
py12306/exceptions/MemberInvalidException.py
+4
-0
__init__.py
py12306/exceptions/__init__.py
+0
-0
api.py
py12306/helpers/api.py
+1
-0
func.py
py12306/helpers/func.py
+12
-1
base.py
py12306/log/base.py
+3
-1
user_log.py
py12306/log/user_log.py
+11
-0
order.py
py12306/order/order.py
+34
-0
job.py
py12306/query/job.py
+34
-19
query.py
py12306/query/query.py
+1
-0
job.py
py12306/user/job.py
+58
-1
user.py
py12306/user/user.py
+16
-0
No files found.
main.py
View file @
0e287096
...
@@ -9,9 +9,12 @@ from py12306.user.user import User
...
@@ -9,9 +9,12 @@ from py12306.user.user import User
def
main
():
def
main
():
# Thread(target=Query.run).start() # 余票查询
# Thread(target=Query.run).start() # 余票查询
create_thread_and_run
(
User
,
'run'
,
wait
=
False
)
# create_thread_and_run(User, 'run', wait=False)
# Query.run()
User
.
run
()
Query
.
run
()
# Query.run()
# Query.run()
while
True
:
sleep
(
1
)
pass
pass
...
...
py12306/config.py
View file @
0e287096
...
@@ -48,5 +48,19 @@ if path.exists(CONFIG_FILE):
...
@@ -48,5 +48,19 @@ if path.exists(CONFIG_FILE):
exec
(
open
(
CONFIG_FILE
,
encoding
=
'utf8'
)
.
read
())
exec
(
open
(
CONFIG_FILE
,
encoding
=
'utf8'
)
.
read
())
class
UserType
:
ADULT
=
1
CHILD
=
2
STUDENT
=
3
SOLDIER
=
4
dicts
=
{
'成人'
:
ADULT
,
'儿童'
:
CHILD
,
'学生'
:
STUDENT
,
'残疾军人、伤残人民警察'
:
SOLDIER
,
}
def
get
(
key
,
default
=
None
):
def
get
(
key
,
default
=
None
):
return
eval
(
key
)
return
eval
(
key
)
py12306/exceptions/MemberInvalidException.py
0 → 100755
View file @
0e287096
class
MemberInvalidException
(
Exception
):
pass
py12306/exceptions/__init__.py
0 → 100644
View file @
0e287096
py12306/helpers/api.py
View file @
0e287096
...
@@ -42,6 +42,7 @@ API_AUTH_UAMAUTHCLIENT = {
...
@@ -42,6 +42,7 @@ API_AUTH_UAMAUTHCLIENT = {
API_USER_INFO
=
{
API_USER_INFO
=
{
'url'
:
BASE_URL_OF_12306
+
'/otn/modifyUser/initQueryUserInfoApi'
'url'
:
BASE_URL_OF_12306
+
'/otn/modifyUser/initQueryUserInfoApi'
}
}
API_USER_PASSENGERS
=
BASE_URL_OF_12306
+
'/otn/confirmPassenger/getPassengerDTOs'
urls
=
{
urls
=
{
"auth"
:
{
# 登录接口
"auth"
:
{
# 登录接口
...
...
py12306/helpers/func.py
View file @
0e287096
...
@@ -75,15 +75,26 @@ def time_now():
...
@@ -75,15 +75,26 @@ def time_now():
return
datetime
.
datetime
.
now
()
return
datetime
.
datetime
.
now
()
def
create_thread_and_run
(
jobs
,
callback_name
,
wait
=
True
):
def
create_thread_and_run
(
jobs
,
callback_name
,
wait
=
True
,
daemon
=
True
):
threads
=
[]
threads
=
[]
if
not
isinstance
(
jobs
,
list
):
if
not
isinstance
(
jobs
,
list
):
jobs
=
[
jobs
]
jobs
=
[
jobs
]
for
job
in
jobs
:
for
job
in
jobs
:
thread
=
threading
.
Thread
(
target
=
getattr
(
job
,
callback_name
))
thread
=
threading
.
Thread
(
target
=
getattr
(
job
,
callback_name
))
thread
.
setDaemon
(
daemon
)
thread
.
start
()
thread
.
start
()
threads
.
append
(
thread
)
threads
.
append
(
thread
)
if
wait
:
if
wait
:
for
thread
in
threads
:
thread
.
join
()
for
thread
in
threads
:
thread
.
join
()
def
dict_find_key_by_value
(
data
,
value
,
default
=
None
):
result
=
[
k
for
k
,
v
in
data
.
items
()
if
v
==
value
]
return
result
.
pop
()
if
len
(
result
)
else
default
def
array_dict_find_by_key_value
(
data
,
key
,
value
,
default
=
None
):
result
=
[
v
for
k
,
v
in
enumerate
(
data
)
if
key
in
v
and
v
[
key
]
==
value
]
return
result
.
pop
()
if
len
(
result
)
else
default
# def test:
# def test:
py12306/log/base.py
View file @
0e287096
...
@@ -22,7 +22,7 @@ class BaseLog:
...
@@ -22,7 +22,7 @@ class BaseLog:
return
self
return
self
@
classmethod
@
classmethod
def
flush
(
cls
,
sep
=
'
\n
'
,
end
=
'
\n
'
,
file
=
None
):
def
flush
(
cls
,
sep
=
'
\n
'
,
end
=
'
\n
'
,
file
=
None
,
exit
=
False
):
self
=
cls
()
self
=
cls
()
if
self
.
quick_log
:
if
self
.
quick_log
:
logs
=
self
.
quick_log
logs
=
self
.
quick_log
...
@@ -41,6 +41,8 @@ class BaseLog:
...
@@ -41,6 +41,8 @@ class BaseLog:
else
:
else
:
if
logs
:
del
self
.
thread_logs
[
current_thread_id
()]
if
logs
:
del
self
.
thread_logs
[
current_thread_id
()]
# print(self.logs)
# print(self.logs)
if
exit
:
sys
.
exit
()
@
classmethod
@
classmethod
def
add_quick_log
(
cls
,
content
):
def
add_quick_log
(
cls
,
content
):
...
...
py12306/log/user_log.py
View file @
0e287096
...
@@ -14,6 +14,9 @@ class UserLog(BaseLog):
...
@@ -14,6 +14,9 @@ class UserLog(BaseLog):
MESSAGE_LOADED_USER_BUT_EXPIRED
=
'用户状态已过期,正在重新登录'
MESSAGE_LOADED_USER_BUT_EXPIRED
=
'用户状态已过期,正在重新登录'
MESSAGE_USER_HEARTBEAT_NORMAL
=
'用户 {} 心跳正常,下次检测 {} 秒后'
MESSAGE_USER_HEARTBEAT_NORMAL
=
'用户 {} 心跳正常,下次检测 {} 秒后'
MESSAGE_GET_USER_PASSENGERS_FAIL
=
'获取用户乘客列表失败,错误原因: {} {} 秒后重试'
MESSAGE_USER_PASSENGERS_IS_INVALID
=
'乘客信息校验失败,在账号 {} 中未找到该乘客: {}'
def
__init__
(
self
):
def
__init__
(
self
):
super
()
.
__init__
()
super
()
.
__init__
()
self
.
init_data
()
self
.
init_data
()
...
@@ -45,3 +48,11 @@ class UserLog(BaseLog):
...
@@ -45,3 +48,11 @@ class UserLog(BaseLog):
self
.
add_log
(
'正在登录用户 {}'
.
format
(
user
.
user_name
))
self
.
add_log
(
'正在登录用户 {}'
.
format
(
user
.
user_name
))
self
.
flush
()
self
.
flush
()
return
self
return
self
@
classmethod
def
print_user_passenger_init_success
(
cls
,
passengers
):
self
=
cls
()
result
=
[
passenger
.
get
(
'name'
)
+
'('
+
passenger
.
get
(
'type_text'
)
+
')'
for
passenger
in
passengers
]
self
.
add_quick_log
(
'# 乘客验证成功 {} #'
.
format
(
', '
.
join
(
result
)))
self
.
flush
()
return
self
py12306/order/order.py
0 → 100644
View file @
0e287096
from
py12306.helpers.app
import
*
from
py12306.helpers.func
import
*
from
py12306.log.user_log
import
UserLog
from
py12306.user.job
import
UserJob
class
Order
:
"""
处理下单
"""
heartbeat
=
60
*
2
users
=
[]
def
__init__
(
self
):
pass
@
classmethod
def
run
(
cls
):
self
=
cls
()
app_available_check
()
self
.
start
()
pass
def
start
(
self
):
self
.
init_users
()
UserLog
.
print_init_users
(
users
=
self
.
users
)
# 多线程维护用户
create_thread_and_run
(
jobs
=
self
.
users
,
callback_name
=
'run'
,
wait
=
False
)
def
init_users
(
self
):
accounts
=
config
.
USER_ACCOUNTS
for
account
in
accounts
:
user
=
UserJob
(
info
=
account
,
user
=
self
)
self
.
users
.
append
(
user
)
py12306/query/job.py
View file @
0e287096
...
@@ -2,6 +2,8 @@ from py12306.helpers.api import LEFT_TICKETS
...
@@ -2,6 +2,8 @@ from py12306.helpers.api import LEFT_TICKETS
from
py12306.helpers.station
import
Station
from
py12306.helpers.station
import
Station
from
py12306.log.query_log
import
QueryLog
from
py12306.log.query_log
import
QueryLog
from
py12306.helpers.func
import
*
from
py12306.helpers.func
import
*
from
py12306.log.user_log
import
UserLog
from
py12306.user.user
import
User
class
Job
:
class
Job
:
...
@@ -15,11 +17,13 @@ class Job:
...
@@ -15,11 +17,13 @@ class Job:
left_station_code
=
''
left_station_code
=
''
arrive_station_code
=
''
arrive_station_code
=
''
account_key
=
0
allow_seats
=
[]
allow_seats
=
[]
allow_train_numbers
=
[]
allow_train_numbers
=
[]
members
=
[]
members
=
[]
member_num
=
0
member_num
=
0
member_num_take
=
0
# 最终提交的人数
member_num_take
=
0
# 最终提交的人数
passengers
=
[]
allow_less_member
=
False
allow_less_member
=
False
interval
=
{}
interval
=
{}
...
@@ -40,6 +44,7 @@ class Job:
...
@@ -40,6 +44,7 @@ class Job:
self
.
left_station_code
=
Station
.
get_station_key_by_name
(
self
.
left_station
)
self
.
left_station_code
=
Station
.
get_station_key_by_name
(
self
.
left_station
)
self
.
arrive_station_code
=
Station
.
get_station_key_by_name
(
self
.
arrive_station
)
self
.
arrive_station_code
=
Station
.
get_station_key_by_name
(
self
.
arrive_station
)
self
.
account_key
=
info
.
get
(
'account_key'
)
self
.
allow_seats
=
info
.
get
(
'seats'
)
self
.
allow_seats
=
info
.
get
(
'seats'
)
self
.
allow_train_numbers
=
info
.
get
(
'train_numbers'
)
self
.
allow_train_numbers
=
info
.
get
(
'train_numbers'
)
self
.
members
=
info
.
get
(
'members'
)
self
.
members
=
info
.
get
(
'members'
)
...
@@ -62,6 +67,9 @@ class Job:
...
@@ -62,6 +67,9 @@ class Job:
:param job:
:param job:
:return:
:return:
"""
"""
if
not
self
.
passengers
:
User
.
check_members
(
self
.
members
,
self
.
account_key
,
call_back
=
self
.
set_passengers
)
QueryLog
.
print_job_start
()
QueryLog
.
print_job_start
()
for
date
in
self
.
left_dates
:
for
date
in
self
.
left_dates
:
response
=
self
.
query_by_date
(
date
)
response
=
self
.
query_by_date
(
date
)
...
@@ -109,26 +117,29 @@ class Job:
...
@@ -109,26 +117,29 @@ class Job:
if
not
self
.
is_has_ticket
(
ticket_info
):
if
not
self
.
is_has_ticket
(
ticket_info
):
continue
continue
allow_seats
=
self
.
allow_seats
if
self
.
allow_seats
else
list
(
config
.
SEAT_TYPES
.
values
())
# 未设置 则所有可用
allow_seats
=
self
.
allow_seats
if
self
.
allow_seats
else
list
(
config
.
SEAT_TYPES
.
values
())
# 未设置 则所有可用
for
seat
in
allow_seats
:
# 检查座位是否有票
self
.
handle_seats
(
allow_seats
,
ticket_info
)
ticket_of_seat
=
ticket_info
[
get_seat_number_by_name
(
seat
)]
if
not
self
.
is_has_ticket_by_seat
(
ticket_of_seat
):
# 座位是否有效
def
handle_seats
(
self
,
allow_seats
,
ticket_info
):
for
seat
in
allow_seats
:
# 检查座位是否有票
ticket_of_seat
=
ticket_info
[
get_seat_number_by_name
(
seat
)]
if
not
self
.
is_has_ticket_by_seat
(
ticket_of_seat
):
# 座位是否有效
continue
QueryLog
.
print_ticket_seat_available
(
left_date
=
self
.
get_info_of_left_date
(),
train_number
=
self
.
get_info_of_train_number
(),
seat_type
=
seat
,
rest_num
=
ticket_of_seat
)
if
not
self
.
is_member_number_valid
(
ticket_of_seat
):
# 乘车人数是否有效
if
self
.
allow_less_member
:
self
.
member_num_take
=
int
(
ticket_of_seat
)
QueryLog
.
print_ticket_num_less_than_specified
(
ticket_of_seat
,
self
)
else
:
QueryLog
.
add_quick_log
(
QueryLog
.
MESSAGE_GIVE_UP_CHANCE_CAUSE_TICKET_NUM_LESS_THAN_SPECIFIED
)
.
flush
()
continue
continue
QueryLog
.
print_ticket_seat_available
(
left_date
=
self
.
get_info_of_left_date
(),
# 检查完成 开始提交订单
train_number
=
self
.
get_info_of_train_number
(),
seat_type
=
seat
,
QueryLog
.
print_ticket_available
(
left_date
=
self
.
get_info_of_left_date
(),
rest_num
=
ticket_of_seat
)
train_number
=
self
.
get_info_of_train_number
(),
if
not
self
.
is_member_number_valid
(
ticket_of_seat
):
# 乘车人数是否有效
rest_num
=
ticket_of_seat
)
if
self
.
allow_less_member
:
print
(
'检查完成 开始提交订单'
)
self
.
member_num_take
=
int
(
ticket_of_seat
)
QueryLog
.
print_ticket_num_less_than_specified
(
ticket_of_seat
,
self
)
else
:
QueryLog
.
add_quick_log
(
QueryLog
.
MESSAGE_GIVE_UP_CHANCE_CAUSE_TICKET_NUM_LESS_THAN_SPECIFIED
)
.
flush
()
continue
# 检查完成 开始提交订单
QueryLog
.
print_ticket_available
(
left_date
=
self
.
get_info_of_left_date
(),
train_number
=
self
.
get_info_of_train_number
(),
rest_num
=
ticket_of_seat
)
print
(
'检查完成 开始提交订单'
)
def
get_results
(
self
,
response
):
def
get_results
(
self
,
response
):
"""
"""
...
@@ -164,6 +175,10 @@ class Job:
...
@@ -164,6 +175,10 @@ class Job:
QueryLog
.
add_stay_log
(
interval
)
QueryLog
.
add_stay_log
(
interval
)
stay_second
(
interval
)
stay_second
(
interval
)
def
set_passengers
(
self
,
passengers
):
UserLog
.
print_user_passenger_init_success
(
passengers
)
self
.
passengers
=
passengers
# 提供一些便利方法
# 提供一些便利方法
def
get_info_of_left_date
(
self
):
def
get_info_of_left_date
(
self
):
return
self
.
ticket_info
[
self
.
INDEX_LEFT_DATE
]
return
self
.
ticket_info
[
self
.
INDEX_LEFT_DATE
]
...
...
py12306/query/query.py
View file @
0e287096
...
@@ -31,6 +31,7 @@ class Query:
...
@@ -31,6 +31,7 @@ class Query:
pass
pass
def
start
(
self
):
def
start
(
self
):
return
# DEBUG
self
.
init_jobs
()
self
.
init_jobs
()
QueryLog
.
print_init_jobs
(
jobs
=
self
.
jobs
)
QueryLog
.
print_init_jobs
(
jobs
=
self
.
jobs
)
while
True
:
while
True
:
...
...
py12306/user/job.py
View file @
0e287096
import
pickle
import
pickle
from
os
import
path
from
os
import
path
from
py12306.helpers.api
import
API_USER_CHECK
,
API_BASE_LOGIN
,
API_AUTH_UAMTK
,
API_AUTH_UAMAUTHCLIENT
,
API_USER_INFO
from
py12306.config
import
*
from
py12306.helpers.api
import
*
from
py12306.helpers.app
import
*
from
py12306.helpers.app
import
*
from
py12306.helpers.auth_code
import
AuthCode
from
py12306.helpers.auth_code
import
AuthCode
from
py12306.helpers.func
import
*
from
py12306.helpers.func
import
*
...
@@ -18,6 +19,9 @@ class UserJob:
...
@@ -18,6 +19,9 @@ class UserJob:
user
=
None
user
=
None
info
=
{}
# 用户信息
info
=
{}
# 用户信息
last_heartbeat
=
None
last_heartbeat
=
None
is_ready
=
False
passengers
=
[]
retry_time
=
5
def
__init__
(
self
,
info
,
user
):
def
__init__
(
self
,
info
,
user
):
self
.
session
=
Request
()
self
.
session
=
Request
()
...
@@ -50,6 +54,7 @@ class UserJob:
...
@@ -50,6 +54,7 @@ class UserJob:
if
self
.
is_first_time
()
or
not
self
.
check_user_is_login
():
if
self
.
is_first_time
()
or
not
self
.
check_user_is_login
():
self
.
handle_login
()
self
.
handle_login
()
self
.
is_ready
=
True
UserLog
.
add_quick_log
(
UserLog
.
MESSAGE_USER_HEARTBEAT_NORMAL
.
format
(
self
.
get_name
(),
self
.
heartbeat
))
.
flush
()
UserLog
.
add_quick_log
(
UserLog
.
MESSAGE_USER_HEARTBEAT_NORMAL
.
format
(
self
.
get_name
(),
self
.
heartbeat
))
.
flush
()
self
.
last_heartbeat
=
time_now
()
self
.
last_heartbeat
=
time_now
()
...
@@ -178,3 +183,55 @@ class UserJob:
...
@@ -178,3 +183,55 @@ class UserJob:
self
.
did_loaded_user
()
self
.
did_loaded_user
()
return
True
return
True
return
None
return
None
def
check_is_ready
(
self
):
return
self
.
is_ready
def
get_user_passengers
(
self
):
if
self
.
passengers
:
return
self
.
passengers
response
=
self
.
session
.
post
(
API_USER_PASSENGERS
)
result
=
response
.
json
()
if
result
.
get
(
'data'
)
and
result
.
get
(
'data'
)
.
get
(
'normal_passengers'
):
self
.
passengers
=
result
.
get
(
'data'
)
.
get
(
'normal_passengers'
)
return
self
.
passengers
else
:
UserLog
.
add_quick_log
(
UserLog
.
MESSAGE_GET_USER_PASSENGERS_FAIL
.
format
(
result
.
get
(
'messages'
,
'-'
),
self
.
retry_time
))
stay_second
(
self
.
retry_time
)
return
self
.
get_user_passengers
()
def
get_passengers_by_members
(
self
,
members
):
"""
获取格式化后的乘客信息
:param members:
:return:
[{
name: '项羽',
type: 1,
id_card: 0000000000000000000,
type_text: '成人'
}]
"""
self
.
get_user_passengers
()
results
=
[]
for
member
in
members
:
child_check
=
array_dict_find_by_key_value
(
results
,
'name'
,
member
)
if
child_check
:
new_member
=
child_check
.
copy
()
new_member
[
'type'
]
=
UserType
.
CHILD
new_member
[
'type_text'
]
=
dict_find_key_by_value
(
UserType
.
dicts
,
int
(
new_member
[
'type'
]))
else
:
passenger
=
array_dict_find_by_key_value
(
self
.
passengers
,
'passenger_name'
,
member
)
if
not
passenger
:
UserLog
.
add_quick_log
(
UserLog
.
MESSAGE_USER_PASSENGERS_IS_INVALID
.
format
(
self
.
user_name
,
member
))
.
flush
(
exit
=
True
)
# TODO 需要优化
new_member
=
{
'name'
:
passenger
.
get
(
'passenger_name'
),
'id_card'
:
passenger
.
get
(
'passenger_id_no'
),
'type'
:
passenger
.
get
(
'passenger_type'
),
'type_text'
:
dict_find_key_by_value
(
UserType
.
dicts
,
int
(
passenger
.
get
(
'passenger_type'
)))
}
results
.
append
(
new_member
)
return
results
py12306/user/user.py
View file @
0e287096
...
@@ -30,3 +30,19 @@ class User:
...
@@ -30,3 +30,19 @@ class User:
for
account
in
accounts
:
for
account
in
accounts
:
user
=
UserJob
(
info
=
account
,
user
=
self
)
user
=
UserJob
(
info
=
account
,
user
=
self
)
self
.
users
.
append
(
user
)
self
.
users
.
append
(
user
)
@
classmethod
def
check_members
(
cls
,
members
,
user_key
,
call_back
):
"""
检测乘客信息
:param passengers:
:return:
"""
self
=
cls
()
for
user
in
self
.
users
:
assert
isinstance
(
user
,
UserJob
)
if
user
.
key
==
user_key
and
user
.
check_is_ready
():
passengers
=
user
.
get_passengers_by_members
(
members
)
call_back
(
passengers
)
pass
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
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 comment