史高治

新随笔 联系 管理
Egの登录oschina:
 
import requests
from fake_useragent import UserAgent as ua
from hashlib import sha1
 
s=requests.Session()
s.verify=False  #忽略ssl证书
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
 
#import ssl  #ssl证书处理法2之添加信任?
#from requests_toolbelt import SSLAdapter
#s.mount('https://', SSLAdapter(ssl.PROTOCOL_TLSv1))
 
def loginOschina(userName,pwd):
    headers={'User-Agent':ua().random}
    indexUrl='https://www.oschina.net/'
    data={'email':userName,'pwd':sha1(pwd.encode()).hexdigest()}
    s.post(indexUrl+'action/user/hash_login?from=',data,headers=headers)
    response=s.get(indexUrl,headers=headers).text
    if '个人资料修改' in response and '退出' in response:
        print('登录成功')
 
if __name__ == '__main__':
    userName='904477955@qq.com'
    pwd='***'
    loginOschina(userName,pwd)
****************************************分割线****************************************
Egの登录知乎:
自动识别倒立汉字验证码:https://github.com/muchrooms/zheye
 
import requests,time
from fake_useragent import UserAgent
from io import BytesIO
from PIL import Image
 
s = requests.session()
def loginZhihu(phone,pwd):
    s.headers={'User-Agent':UserAgent().random} #下文不必每次请求都写1次headers参数了
    xsrf=s.get('https://www.zhihu.com/').cookies['_xsrf']
    r=int(time.time()*1000)
    captchaUrl=f'https://www.zhihu.com/captcha.gif?r={r}&type=login&lang=cn'
    captcha=s.get(captchaUrl).content
    Image.open(BytesIO(captcha)).show() #BytesIO把二进制内容,转为内存中的文件对象
    # 知乎最新的汉字验证码,第1个字的坐标是[23,23],第2个是[46,23],第2个是[69,23]……
    captcha=tuple(int(x)*23 for x in input('输入各倒字的序号如1-3,自1始,以-分隔:').split('-'))
    if  len(captcha)==2:    #目前的验证码,大部分时候是两个倒立汉字,偶尔是一个
        captcha='{"img_size":[200,44],"input_points":[[%s,23],[%s,23]]}' % captcha
    elif len(captcha)==1:    #知乎的captcha参数的值,是str,而非{}类型
        captcha='{"img_size":[200,44],"input_points":[[%s,23]]}' % captcha
    # print(captcha)
    data={'_xsrf':xsrf,'phone_num':phone,'password':pwd,'captcha':captcha,'captcha_type':'cn'}
    response=s.post('https://www.zhihu.com/login/phone_num',data=data).text
    print(response) #r为0表示登录成功,r为1或无r则失败
 
loginZhihu('1388908**41','登录密码')
****************************************分割线****************************************
Egの登录12306:
 
import requests,json
from fake_useragent import UserAgent
from io import BytesIO
from PIL import Image
 
codeImageUrl='https://kyfw.12306.cn/passport/captcha/captcha-image'
codeCheckUrl='https://kyfw.12306.cn/passport/captcha/captcha-check'
loginUrl='https://kyfw.12306.cn/passport/web/login'
 
def captchaRecognition():
    # 把验证码图下到内存,左上角为原点,用截图软件手动获取各匹配图片的横、纵坐标
    captcha=s.get(codeImageUrl).content
    Image.open(BytesIO(captcha)).show()
 
    axises=input("各匹配图片的横&纵坐标,均以半角逗号分隔:")
    codeData={'answer':axises,'login_site':'E','rand':'sjrand'}
    codeCheckResult=s.post(codeCheckUrl,codeData).text
    if json.loads(codeCheckResult)['result_code'] == '4': # 此处的4是str,下文的0是int
        print('验证码通过')
    else:
        print('验证码错误')
        exit()
 
def login():
    user=input('please input your login ID>>>')
    pwd=input('please input your login Password>>>')
    loginData={'username':user,'password':pwd,'appid':'otn'}
    loginResult=s.post(loginUrl,loginData).text
    if json.loads(loginResult)['result_code'] == 0:
        print('登录成功')
    else:
        print('登录失败')
 
if __name__ == '__main__':
    s=requests.session()
    h={'User-Agent':UserAgent().random,'Referer':'https://kyfw.12306.cn/otn/login/init'}
    s.headers=h
 
    # 用verify=False移除SSL认证时,禁用因其产生的安全请求警告
    from requests.packages.urllib3.exceptions import InsecureRequestWarning
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    s.verify=False  # 移除SSL证书验证
 
    captchaRecognition()
    login()
****************************************分割线****************************************
Egの12306余票及票价的查询:
 
E:\py\RestTickets_Prices.py:
 
'''控制台查余票
 
Usage:
  tickets [-gdtkz] <from> <to> <date>
 
Options:
  -h,--help   显示帮助菜单
  -g          高铁
  -d          动车
  -t          特快
  -k          快速
  -z          直达
 
Example:
  tickets 深圳 北京 2018-02-09
'''
from docopt import docopt
from colorama import Fore,init
from prettytable import PrettyTable
from fake_useragent import UserAgent
import os,re,json,requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
init(convert=True)
 
def run():
    if not os.path.isfile('E:/各地车站代码.txt'):
        codeOfAllStations()
    with open('E:/各地车站代码.txt',encoding='utf8') as f:
        stations=json.loads(f.read())
    rtp=RestTicketsAndPrices(stations)
    rtp.restTickets()
 
def codeOfAllStations():   #获取各地车站的大写英文代码
    stationsUrl='https://kyfw.12306.cn/otn/resources/js/framework/station_name.js'
    html=requests.get(stationsUrl).text
    pattern=re.compile('@.+?\|(.+?)\|(.+?)\|')
    stations=dict(pattern.findall(html))
    stations.update(dict(zip(stations.values(),stations.keys())))
    with open('E:/各地车站代码.txt','w',encoding='utf8') as f:
        f.write(json.dumps(stations,ensure_ascii=False,indent='').replace(": ",":"))
 
class RestTicketsAndPrices:
    def __init__(self,stations):
        self.stations=stations
 
    def restTickets(self):
        arguments=docopt(__doc__)
        date = arguments['<date>']
        fr=self.stations.get(arguments['<from>'])
        to=self.stations.get(arguments['<to>'])
        url=f'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={date}&\
leftTicketDTO.from_station={fr}&leftTicketDTO.to_station={to}&purpose_codes=ADULT'
        r=requests.get(url,verify=False)
        if 'w3.org' in r.text:
            print('车站或日期有误,或网络堵塞,重试下。。。')
            return
        rows=r.json()['data']['result']
        self.mySqlTableStyle(rows)
 
    def mySqlTableStyle(self,rows):
        pt=PrettyTable('车次,始发,终点,出站,到站,出时,到时,历时,硬卧,硬座,无座,二等,一等'.split(','))
        pattern=re.compile('\|+')
        fails=0 #没能返回票价的车次数量
        for row in rows:
            line=pattern.split(row)
            prices=self.priceOfTrainSeats(line)
            fails+=prices.get('fail',0)
            line[4:8]=[self.stations.get(x) for x in line[4:8]]
            if line[-2]=='1413':   #普铁:硬卧,硬座,无座,--,--;没取软卧和软座
                pt.add_row(line[3:11]+[line[22],line[23],line[21],'--','--'])
                pt.add_row(['  ']*8+[prices['A3'],prices['A1'],prices['WZ'],'  ','  '])
            elif set(line[-2])==set('OM9'):    #高铁:--,--,--,二等,一等;没取特等
                pt.add_row(line[3:11]+['--']*3+line[21:23])
                pt.add_row(['  ']*11+[prices['O'],prices['M']])
            else:   #动车/城际:--,--,无座,二等,一等;--,--,--,二等,动卧
                if set(line[-2])==set('OOM') or (set(line[-2])==set('OF') and len(line[-2])==3):
                    pt.add_row(line[3:11]+['--']*2+line[20:23])
                elif set(line[-2])==set('OF'):
                    pt.add_row(line[3:11]+['--']*3+line[20:22])
                pt.add_row(['  ']*10+[prices.get('WZ','  '),prices['O'],prices.get('M',prices['F'])])
        for row in pt._rows:
            for column in [5,7,9]:
                row[column]=Fore.RED+str(row[column])+Fore.RESET
        print(pt)
        if fails:print(f'网络卡顿,未显示的{fails}个车次的票价请稍后重试')
 
    def priceOfTrainSeats(self,n):
        n[13]=f'{n[13][:4]}-{n[13][4:6]}-{n[13][6:]}'
        priceUrl=f'https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no={n[2]}&\
from_station_no={n[16]}&to_station_no={n[17]}&seat_types={n[-2]}&train_date={n[13]}'
        h={'User-Agent':UserAgent().random}
        try:prices=requests.get(priceUrl,headers=h).json()['data']
        #下行代码顺次表示:硬座、软座、硬卧、软卧、特等、无座、二等、一等、动卧
        except:prices=dict(zip(['A1','A2','A3','A4','A9','WZ','O','M','F'],['  ']*9),fail=1)
        finally:return prices
 
if __name__ == '__main__':
    run()
*********************分割线*********************
E:\py\setup.py:
 
# 程序运行の法1:Python命令 程序脚本名 各参数
# cmd='python "E:/py/RestTickets_Prices.py" 深圳 北京 2018-02-05'
# import os
# os.system(cmd)
 
# 程序运行の法2:自定义个可执行命令如tickets 各参数
# 本py放在项目根下,并在此处执行命令:python "本安装脚本的路径名" install
from setuptools import setup,find_packages
 
setup(
    name='TrainTickets', #包名,若上传到pypi,可通过该名来pip install
    version='1.0',  #只能是数值
    keywords=('12306','余票','票价'),
    description='cmd中的运行示例:tickets 深圳 北京 2018-02-09',
    long_description='出行日出发站至目的站,各车次的各种座位的余票数及票价',
    url='',
    author='程勇',
    author_email='904477955@qq.com',
    license='MIT',
    platforms='any',
    py_modules=['RestTickets_Prices',],  #packages=find_packages():ModuleNotFound
    include_package_data=False,
    install_requires=['docopt','colorama','prettytable','requests','fake_useragent'],
    entry_points={'console_scripts':['tickets=RestTickets_Prices:run',]},
)   #['exe名1=项目.子包1.模块名1:入口函数1','exe名2=项目.模块名2:入口函数2',]
posted on 2017-10-19 17:40  史高治  阅读(438)  评论(0编辑  收藏  举报