├── .gitignore ├── Pipfile ├── Pipfile.lock ├── README.md ├── app ├── __init__.py └── utils │ ├── __init__.py │ ├── base.py │ ├── bean_app.py │ ├── bean_vip.py │ ├── clock.py │ ├── clock_app.py │ ├── comment.py │ ├── utils.py │ └── web_browser.py ├── data ├── comment.txt ├── cookie copy.txt └── jd.log └── manage.py /.gitignore: -------------------------------------------------------------------------------- 1 | .venv 2 | img 3 | test* 4 | cookie.txt 5 | __pycache__ 6 | *.pyc 7 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.mirrors.ustc.edu.cn/simple/" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | requests = "*" 8 | click = "*" 9 | furl = "*" 10 | requests-html = "*" 11 | pyqt5 = "==5.10.1" 12 | 13 | [dev-packages] 14 | yapf = "*" 15 | 16 | [requires] 17 | python_version = "3.6" 18 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "ebd8270e26b58f24c3fe773190f9a1d6802e1479aa5353e1511e755384b3fa20" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.6" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.mirrors.ustc.edu.cn/simple/", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "appdirs": { 20 | "hashes": [ 21 | "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", 22 | "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" 23 | ], 24 | "version": "==1.4.3" 25 | }, 26 | "beautifulsoup4": { 27 | "hashes": [ 28 | "sha256:5279c36b4b2ec2cb4298d723791467e3000e5384a43ea0cdf5d45207c7e97169", 29 | "sha256:6135db2ba678168c07950f9a16c4031822c6f4aec75a65e0a97bc5ca09789931", 30 | "sha256:dcdef580e18a76d54002088602eba453eec38ebbcafafeaabd8cab12b6155d57" 31 | ], 32 | "version": "==4.8.1" 33 | }, 34 | "bs4": { 35 | "hashes": [ 36 | "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a" 37 | ], 38 | "version": "==0.0.1" 39 | }, 40 | "certifi": { 41 | "hashes": [ 42 | "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", 43 | "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef" 44 | ], 45 | "version": "==2019.9.11" 46 | }, 47 | "chardet": { 48 | "hashes": [ 49 | "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", 50 | "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" 51 | ], 52 | "version": "==3.0.4" 53 | }, 54 | "click": { 55 | "hashes": [ 56 | "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", 57 | "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" 58 | ], 59 | "index": "pypi", 60 | "version": "==7.0" 61 | }, 62 | "cssselect": { 63 | "hashes": [ 64 | "sha256:f612ee47b749c877ebae5bb77035d8f4202c6ad0f0fc1271b3c18ad6c4468ecf", 65 | "sha256:f95f8dedd925fd8f54edb3d2dfb44c190d9d18512377d3c1e2388d16126879bc" 66 | ], 67 | "version": "==1.1.0" 68 | }, 69 | "fake-useragent": { 70 | "hashes": [ 71 | "sha256:c104998b750eb097eefc28ae28e92d66397598d2cf41a31aa45d5559ef1adf35" 72 | ], 73 | "version": "==0.1.11" 74 | }, 75 | "furl": { 76 | "hashes": [ 77 | "sha256:c0e0231a1feee2acd256574b7033df3144775451c610cb587060d6a0d7e0b621", 78 | "sha256:f4d6f1e5479c376a5b7bdc62795d736d8c1b2a754f366a2ad2816e46e946e22e" 79 | ], 80 | "index": "pypi", 81 | "version": "==2.1.0" 82 | }, 83 | "idna": { 84 | "hashes": [ 85 | "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", 86 | "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" 87 | ], 88 | "version": "==2.8" 89 | }, 90 | "lxml": { 91 | "hashes": [ 92 | "sha256:02ca7bf899da57084041bb0f6095333e4d239948ad3169443f454add9f4e9cb4", 93 | "sha256:096b82c5e0ea27ce9138bcbb205313343ee66a6e132f25c5ed67e2c8d960a1bc", 94 | "sha256:0a920ff98cf1aac310470c644bc23b326402d3ef667ddafecb024e1713d485f1", 95 | "sha256:17cae1730a782858a6e2758fd20dd0ef7567916c47757b694a06ffafdec20046", 96 | "sha256:17e3950add54c882e032527795c625929613adbd2ce5162b94667334458b5a36", 97 | "sha256:1f4f214337f6ee5825bf90a65d04d70aab05526c08191ab888cb5149501923c5", 98 | "sha256:2e8f77db25b0a96af679e64ff9bf9dddb27d379c9900c3272f3041c4d1327c9d", 99 | "sha256:4dffd405390a45ecb95ab5ab1c1b847553c18b0ef8ed01e10c1c8b1a76452916", 100 | "sha256:6b899931a5648862c7b88c795eddff7588fb585e81cecce20f8d9da16eff96e0", 101 | "sha256:726c17f3e0d7a7200718c9a890ccfeab391c9133e363a577a44717c85c71db27", 102 | "sha256:760c12276fee05c36f95f8040180abc7fbebb9e5011447a97cdc289b5d6ab6fc", 103 | "sha256:796685d3969815a633827c818863ee199440696b0961e200b011d79b9394bbe7", 104 | "sha256:891fe897b49abb7db470c55664b198b1095e4943b9f82b7dcab317a19116cd38", 105 | "sha256:a471628e20f03dcdfde00770eeaf9c77811f0c331c8805219ca7b87ac17576c5", 106 | "sha256:a63b4fd3e2cabdcc9d918ed280bdde3e8e9641e04f3c59a2a3109644a07b9832", 107 | "sha256:b0b84408d4eabc6de9dd1e1e0bc63e7731e890c0b378a62443e5741cfd0ae90a", 108 | "sha256:be78485e5d5f3684e875dab60f40cddace2f5b2a8f7fede412358ab3214c3a6f", 109 | "sha256:c27eaed872185f047bb7f7da2d21a7d8913457678c9a100a50db6da890bc28b9", 110 | "sha256:c81cb40bff373ab7a7446d6bbca0190bccc5be3448b47b51d729e37799bb5692", 111 | "sha256:d11874b3c33ee441059464711cd365b89fa1a9cf19ae75b0c189b01fbf735b84", 112 | "sha256:e9c028b5897901361d81a4718d1db217b716424a0283afe9d6735fe0caf70f79", 113 | "sha256:fe489d486cd00b739be826e8c1be188ddb74c7a1ca784d93d06fda882a6a1681" 114 | ], 115 | "version": "==4.4.1" 116 | }, 117 | "orderedmultidict": { 118 | "hashes": [ 119 | "sha256:04070bbb5e87291cc9bfa51df413677faf2141c73c61d2a5f7b26bea3cd882ad", 120 | "sha256:43c839a17ee3cdd62234c47deca1a8508a3f2ca1d0678a3bf791c87cf84adbf3" 121 | ], 122 | "version": "==1.0.1" 123 | }, 124 | "parse": { 125 | "hashes": [ 126 | "sha256:a5fca7000c6588d77bc65c28f3f21bfce03b5e44daa8f9f07c17fe364990d717" 127 | ], 128 | "version": "==1.12.1" 129 | }, 130 | "pyee": { 131 | "hashes": [ 132 | "sha256:a9c9b60e8693a260dd942ef5a71358cfcbba15792d5e72caf0e3c891c4e91c3b", 133 | "sha256:dbe44f61c40a995d2bdfd83d9fcb87ae025882d2c7f366513325e3daa09d7ede" 134 | ], 135 | "version": "==6.0.0" 136 | }, 137 | "pyppeteer": { 138 | "hashes": [ 139 | "sha256:51fe769b722a1718043b74d12c20420f29e0dd9eeea2b66652b7f93a9ad465dd" 140 | ], 141 | "version": "==0.0.25" 142 | }, 143 | "pyqt5": { 144 | "hashes": [ 145 | "sha256:1e652910bd1ffd23a3a48c510ecad23a57a853ed26b782cd54b16658e6f271ac", 146 | "sha256:4db7113f464c733a99fcb66c4c093a47cf7204ad3f8b3bda502efcc0839ac14b", 147 | "sha256:9c17ab3974c1fc7bbb04cc1c9dae780522c0ebc158613f3025fccae82227b5f7", 148 | "sha256:f6035baa009acf45e5f460cf88f73580ad5dc0e72330029acd99e477f20a5d61" 149 | ], 150 | "index": "pypi", 151 | "version": "==5.10.1" 152 | }, 153 | "pyquery": { 154 | "hashes": [ 155 | "sha256:07987c2ed2aed5cba29ff18af95e56e9eb04a2249f42ce47bddfb37f487229a3", 156 | "sha256:4771db76bd14352eba006463656aef990a0147a0eeaf094725097acfa90442bf" 157 | ], 158 | "version": "==1.4.0" 159 | }, 160 | "requests": { 161 | "hashes": [ 162 | "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", 163 | "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" 164 | ], 165 | "index": "pypi", 166 | "version": "==2.22.0" 167 | }, 168 | "requests-html": { 169 | "hashes": [ 170 | "sha256:7e929ecfed95fb1d0994bb368295d6d7c4d06b03fcb900c33d7d0b17e6003947", 171 | "sha256:cb8a78cf829c4eca9d6233f28524f65dd2bfaafb4bdbbc407f0a0b8f487df6e2" 172 | ], 173 | "index": "pypi", 174 | "version": "==0.10.0" 175 | }, 176 | "sip": { 177 | "hashes": [ 178 | "sha256:09f9a4e6c28afd0bafedb26ffba43375b97fe7207bd1a0d3513f79b7d168b331", 179 | "sha256:105edaaa1c8aa486662226360bd3999b4b89dd56de3e314d82b83ed0587d8783", 180 | "sha256:1bb10aac55bd5ab0e2ee74b3047aa2016cfa7932077c73f602a6f6541af8cd51", 181 | "sha256:265ddf69235dd70571b7d4da20849303b436192e875ce7226be7144ca702a45c", 182 | "sha256:52074f7cb5488e8b75b52f34ec2230bc75d22986c7fe5cd3f2d266c23f3349a7", 183 | "sha256:5ff887a33839de8fc77d7f69aed0259b67a384dc91a1dc7588e328b0b980bde2", 184 | "sha256:74da4ddd20c5b35c19cda753ce1e8e1f71616931391caeac2de7a1715945c679", 185 | "sha256:7d69e9cf4f8253a3c0dfc5ba6bb9ac8087b8239851f22998e98cb35cfe497b68", 186 | "sha256:97bb93ee0ef01ba90f57be2b606e08002660affd5bc380776dd8b0fcaa9e093a", 187 | "sha256:cf98150a99e43fda7ae22abe655b6f202e491d6291486548daa56cb15a2fcf85", 188 | "sha256:d9023422127b94d11c1a84bfa94933e959c484f2c79553c1ef23c69fe00d25f8", 189 | "sha256:e72955e12f4fccf27aa421be383453d697b8a44bde2cc26b08d876fd492d0174" 190 | ], 191 | "version": "==4.19.8" 192 | }, 193 | "six": { 194 | "hashes": [ 195 | "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", 196 | "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" 197 | ], 198 | "version": "==1.12.0" 199 | }, 200 | "soupsieve": { 201 | "hashes": [ 202 | "sha256:605f89ad5fdbfefe30cdc293303665eff2d188865d4dbe4eb510bba1edfbfce3", 203 | "sha256:b91d676b330a0ebd5b21719cb6e9b57c57d433671f65b9c28dd3461d9a1ed0b6" 204 | ], 205 | "version": "==1.9.4" 206 | }, 207 | "tqdm": { 208 | "hashes": [ 209 | "sha256:abc25d0ce2397d070ef07d8c7e706aede7920da163c64997585d42d3537ece3d", 210 | "sha256:dd3fcca8488bb1d416aa7469d2f277902f26260c45aa86b667b074cd44b3b115" 211 | ], 212 | "version": "==4.36.1" 213 | }, 214 | "urllib3": { 215 | "hashes": [ 216 | "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", 217 | "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86" 218 | ], 219 | "version": "==1.25.6" 220 | }, 221 | "w3lib": { 222 | "hashes": [ 223 | "sha256:847704b837b2b973cddef6938325d466628e6078266bc2e1f7ac49ba85c34823", 224 | "sha256:8b1854fef570b5a5fc84d960e025debd110485d73fd283580376104762774315" 225 | ], 226 | "version": "==1.21.0" 227 | }, 228 | "websockets": { 229 | "hashes": [ 230 | "sha256:049e694abe33f8a1d99969fee7bfc0ae6761f7fd5f297c58ea933b27dd6805f2", 231 | "sha256:73ce69217e4655783ec72ce11c151053fcbd5b837cc39de7999e19605182e28a", 232 | "sha256:83e63aa73331b9ca21af61df8f115fb5fbcba3f281bee650a4ad16a40cd1ef15", 233 | "sha256:882a7266fa867a2ebb2c0baaa0f9159cabf131cf18c1b4270d79ad42f9208dc5", 234 | "sha256:8c77f7d182a6ea2a9d09c2612059f3ad859a90243e899617137ee3f6b7f2b584", 235 | "sha256:8d7a20a2f97f1e98c765651d9fb9437201a9ccc2c70e94b0270f1c5ef29667a3", 236 | "sha256:a7affaeffbc5d55681934c16bb6b8fc82bb75b175e7fd4dcca798c938bde8dda", 237 | "sha256:c82e286555f839846ef4f0fdd6910769a577952e1e26aa8ee7a6f45f040e3c2b", 238 | "sha256:e906128532a14b9d264a43eb48f9b3080d53a9bda819ab45bf56b8039dc606ac", 239 | "sha256:e9102043a81cdc8b7c8032ff4bce39f6229e4ac39cb2010946c912eeb84e2cb6", 240 | "sha256:f5cb2683367e32da6a256b60929a3af9c29c212b5091cf5bace9358d03011bf5" 241 | ], 242 | "version": "==8.0.2" 243 | } 244 | }, 245 | "develop": { 246 | "yapf": { 247 | "hashes": [ 248 | "sha256:02ace10a00fa2e36c7ebd1df2ead91dbfbd7989686dc4ccbdc549e95d19f5780", 249 | "sha256:6f94b6a176a7c114cfa6bad86d40f259bbe0f10cf2fa7f2f4b3596fc5802a41b" 250 | ], 251 | "index": "pypi", 252 | "version": "==0.28.0" 253 | } 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 京东自动完成脚本 2 | 1. 京东订单自动评价脚本 3 | 2. 京东app签到领京豆 4 | 5 | ## 一、安装 6 | ### 1. 程序依赖 7 | 1. python3.5+ 8 | 9 | ### 2. 安装配置 10 | 1. 安装pipenv 11 | 2. 安装模块 12 | ``` 13 | pipenv install 14 | ``` 15 | 16 | ## 二、使用 17 | ### 1. 京东订单自动评价使用方法 18 | #### 1. 增加自动评论内容 19 | 可以打开comment.txt文件, 每行一个评论内容, 在评价时会自动随机选取一条进行评价 20 | , 如果有比较好的评论, 希望可以提交给我, 我添加到项目中 21 | 22 | #### 2. 使用 23 | ``` 24 | python manage.py comment 25 | ``` 26 | 如果没有登录或者登录已失效, 会弹出京东的登录窗口, 登录成功后, 点击x关闭窗口即可 27 | 28 | ### 2. 京东app签到领京豆 29 | ``` 30 | python manage.py bean_app 31 | ``` 32 | 33 | ## 三、 联系方式 34 | QQ: 2387813033 35 | QQ群: 252799167 36 | 37 | 如果有用, 麻烦动动小手, 点个star, 非常感谢 38 | -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aox-lei/aox_jd_auto_script/093cca5524fbcb0f4915aaad14886428ab343369/app/__init__.py -------------------------------------------------------------------------------- /app/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aox-lei/aox_jd_auto_script/093cca5524fbcb0f4915aaad14886428ab343369/app/utils/__init__.py -------------------------------------------------------------------------------- /app/utils/base.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | import os 3 | import requests 4 | import json 5 | from requests_html import HTML 6 | from app.utils.web_browser import openWithWebBrowser 7 | 8 | 9 | class base(object): 10 | COOKIE_PATH = './data/cookie.txt' 11 | HOME_URL = 'https://home.jd.com/' 12 | LOGIN_URL = 'https://passport.jd.com/new/login.aspx' 13 | INDEX_URL = 'https://www.jd.com/' 14 | 15 | def __init__(self, ): 16 | self.session = requests.Session() 17 | self.load_cookie() 18 | 19 | def check_login(self): 20 | ''' 检测登录 ''' 21 | result = self.session.get(self.HOME_URL, verify=False) 22 | 23 | html = HTML(html=result.text) 24 | 25 | if html.find('title', first=True).text == '我的京东': 26 | return True 27 | else: 28 | return False 29 | 30 | def load_cookie(self): 31 | if os.path.exists(self.COOKIE_PATH): 32 | with open(self.COOKIE_PATH, 'r') as f: 33 | cookies = f.read() 34 | try: 35 | cookies = json.loads(cookies) 36 | except Exception as e: 37 | return False 38 | cookies = requests.utils.cookiejar_from_dict(cookies, 39 | cookiejar=None, 40 | overwrite=True) 41 | self.session.cookies = cookies 42 | return True 43 | return False 44 | 45 | 46 | class Login(base): 47 | def login(self): 48 | ''' selenium 登录京东 ''' 49 | self.clean_cookie() 50 | if self.load_cookie() and self.check_login(): 51 | return True 52 | 53 | cookies = openWithWebBrowser(self.LOGIN_URL) 54 | with open(self.COOKIE_PATH, 'w') as f: 55 | f.write(json.dumps(cookies)) 56 | 57 | if self.load_cookie() and self.check_login(): 58 | return True 59 | 60 | return False 61 | 62 | def clean_cookie(self): 63 | with open(self.COOKIE_PATH, 'w') as f: 64 | f.write('{}') 65 | 66 | return True 67 | -------------------------------------------------------------------------------- /app/utils/bean_app.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | ''' 3 | 京东APP签到领京豆 4 | ''' 5 | import logging 6 | import json 7 | import random 8 | from app.utils.base import base 9 | 10 | 11 | class bean_app(base): 12 | INFO_URL = 'https://api.m.jd.com/client.action?functionId=queryBeanIndex' 13 | SIGN_URL = 'https://api.m.jd.com/client.action?functionId=signBeanStart' 14 | POKER_URL = 'https://api.m.jd.com/client.action?functionId=getCardResult' 15 | client_info = {'client': 'ld', 'clientVersion': '1.0.0'} 16 | 17 | def run(self): 18 | self.sign() 19 | try: 20 | data = self.fetch_data(self.INFO_URL) 21 | except Exception as e: 22 | logging.exception(e) 23 | return False 24 | 25 | # 根据测试, 2 表示已签到, 4 表示未签到, 5 表示未登录 26 | signed = (data['status'] == '2') 27 | sign_days = int(data['continuousDays']) 28 | beans_count = int(data['totalUserBean']) 29 | 30 | logging.info('今日已签到: {}; 签到天数: {}; 现有京豆: {}'.format( 31 | signed, sign_days, beans_count)) 32 | return signed 33 | 34 | def sign(self): 35 | try: 36 | data = self.fetch_data(self.SIGN_URL) 37 | except Exception as e: 38 | logging.exception(e) 39 | return False 40 | 41 | sign_success = (data['status'] == '1') 42 | message = data['signShowBean']['signText'] 43 | message = message.replace('signAward', 44 | data['signShowBean']['signAward']) 45 | logging.info('签到成功: {}; Message: {}'.format(sign_success, message)) 46 | 47 | if 'awardList' in data['signShowBean']: 48 | # "complated": 原文如此, 服务端的拼写错误... 49 | poker_picked = data['signShowBean']['complated'] 50 | 51 | if not poker_picked: 52 | pick_success = self.pick_poker(data['signShowBean']) 53 | # 同时成功才视为签到成功 54 | sign_success &= pick_success 55 | 56 | return sign_success 57 | 58 | def pick_poker(self, poker): 59 | poker_to_pick = random.randint(1, len(poker['awardList'])) 60 | 61 | try: 62 | payload = {'body': json.dumps({'index': poker_to_pick})} 63 | data = self.fetch_data(self.POKER_URL, payload=payload) 64 | except Exception as e: 65 | logging.exception(e) 66 | return False 67 | 68 | message = data['signText'].replace('signAward', data['signAward']) 69 | self.logger.info('翻牌成功: {}'.format(message)) 70 | return True 71 | 72 | def fetch_data(self, url, payload=None): 73 | if payload is not None: 74 | payload = dict(payload.items() + self.client_info.items()) 75 | else: 76 | payload = self.client_info 77 | 78 | r = self.session.get(url, params=payload, verify=False) 79 | 80 | try: 81 | as_json = r.json() 82 | except Exception: 83 | logging.exception() 84 | 85 | if as_json['code'] != '0' or 'errorCode' in as_json or 'errorMessage' in as_json: 86 | error_msg = as_json.get('echo') or as_json.get( 87 | 'errorMessage') or str(as_json) 88 | error_code = as_json.get('errorCode') or as_json.get('code') 89 | logging.error('error_msg: %s, error_code: %d' % (error_msg, 90 | int(error_code))) 91 | return False 92 | # 请求成功 93 | return as_json['data'] 94 | -------------------------------------------------------------------------------- /app/utils/bean_vip.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | ''' 3 | 京东会员页面签到领京豆 4 | ''' 5 | import re 6 | import logging 7 | import requests 8 | from requests_html import HTML 9 | from app.utils.base import base 10 | 11 | 12 | class bean_vip(base): 13 | INFO_URL = 'https://vip.jd.com/member/getUserInfo.html' 14 | SIGN_URL = 'https://vip.jd.com/common/signin.html' 15 | INDEX_URL = 'https://vip.jd.com' 16 | page_data = '' 17 | 18 | def run(self): 19 | self.sign() 20 | page_data = self._get_page_data() 21 | signed = '已签到' in HTML(html=page_data).find('.sign-in')[0].text 22 | 23 | detail = self.session.get(self.INFO_URL, verify=False).json() 24 | 25 | if detail['success']: 26 | user_info = detail['result']['userInfo'] 27 | beans_count = user_info['userJingBeanNum'] 28 | logging.info('今日已签到: {}; 现在有 {} 个京豆.'.format(signed, beans_count)) 29 | 30 | else: 31 | logging.info('今日已签到: {}'.format(signed)) 32 | 33 | return signed 34 | 35 | def sign(self): 36 | token = self._get_token() 37 | if not token: 38 | return False 39 | payload = {'token': token} 40 | 41 | response = self.session.get(self.SIGN_URL, params=payload, verify=False) 42 | if response['success']: 43 | # 签到成功, 获得若干个京豆 44 | beans_get = response['result'].get('jdnum') 45 | message = '签到成功, 获得 {} 个京豆.'.format( 46 | beans_get) if beans_get else '签到成功.' 47 | logging.info(message) 48 | return True 49 | else: 50 | message = response['resultTips'] 51 | logging.error('签到失败: {}'.format(message)) 52 | return False 53 | 54 | def _get_token(self): 55 | html = self._get_page_data() 56 | pattern = r'token:\s*"(\d+)"' 57 | 58 | token = re.search(pattern, html) 59 | 60 | if token: 61 | token = token.group(1) 62 | 63 | if not token: 64 | logging.error('token 未找到.') 65 | return False 66 | return token 67 | 68 | def _get_page_data(self): 69 | if not self.page_data: 70 | try: 71 | self.page_data = self.session.get( 72 | self.INDEX_URL, verify=False).text 73 | except Exception as e: 74 | logging.exception(e) 75 | return self.page_data 76 | -------------------------------------------------------------------------------- /app/utils/clock.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | import logging 3 | from app.utils.base import base 4 | 5 | 6 | class clock(base): 7 | INDEX_URL = 'https://bk.jd.com/m/channel/login/daka.html' 8 | LOGIN_URL = 'https://home.m.jd.com' 9 | SIGN_URL = 'https://bk.jd.com/m/channel/login/clock.html' 10 | TEST_URL = INDEX_URL 11 | JOB_GD_URL = 'https://bk.jd.com/m/channel/login/recDakaGb.html' 12 | 13 | def run(self): 14 | self.sign() 15 | 16 | def sign(self): 17 | try: 18 | data = self.fetch_data(self.SIGN_URL) 19 | logging.info('打卡成功: ' + data['resultMessage']) 20 | return True 21 | except Exception as e: 22 | if e.code == '0003': 23 | # 已打卡 7 次, 需要先去 "任务" 里完成一个领钢镚任务... 24 | logging.info('已打卡 7 次, 去完成领钢镚任务...') 25 | pick_success = self.pick_gb() 26 | 27 | if pick_success: 28 | # 钢镚领取成功, 重新开始打卡任务 29 | return self.sign() 30 | else: 31 | e.message = '钢镚领取任务未成功完成.' 32 | 33 | logging.error('打卡失败: ' + e.message) 34 | return False 35 | 36 | def pick_gb(self): 37 | # 任务列表在 https://bk.jd.com/m/money/doJobMoney.html 中看 38 | # 领钢镚的任务的 id 是 82 39 | try: 40 | data = self.fetch_data(self.JOB_GD_URL) 41 | self.logger.info('钢镚领取成功: {}'.format(data['resultMessage'])) 42 | return True 43 | 44 | except Exception as e: 45 | self.logger.error('领钢镚 -> 钢镚领取失败: {}'.format(e.message)) 46 | return False 47 | 48 | def fetch_data(self, url, payload=None): 49 | r = self.session.get(url, params=payload) 50 | try: 51 | as_json = r.json() 52 | except ValueError: 53 | raise Exception( 54 | 'unexpected response: url: {}; http code: {}'.format( 55 | url, r.status_code), 56 | response=r) 57 | 58 | if as_json['success']: 59 | # 请求成功 60 | return as_json 61 | 62 | else: 63 | error_msg = as_json.get('resultMessage') or str(as_json) 64 | error_code = as_json.get('resultCode') 65 | raise Exception(error_msg, error_code) 66 | -------------------------------------------------------------------------------- /app/utils/clock_app.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | import logging 3 | from app.utils.base import base 4 | 5 | 6 | class clock_app(base): 7 | INDEX_URL = 'https://m.jr.jd.com/spe/qyy/main/index.html?userType=41' 8 | SIGN_URL = 'https://ms.jr.jd.com/gw/generic/base/h5/m/baseSignInEncrypt' 9 | TEST_URL = 'https://ms.jr.jd.com/gw/generic/base/h5/m/baseGetMessByGroupType' 10 | 11 | def run(self): 12 | self.sign() 13 | pass 14 | 15 | def sign(self): 16 | payload = { 17 | 'reqData': '{}', 18 | 'sid': self.session.cookies.get('sid'), 19 | 'source': 'jrm' 20 | } 21 | 22 | r = self.session.post(self.SIGN_URL, data=payload, verify=False) 23 | as_json = r.json() 24 | 25 | if 'resultData' in as_json: 26 | result_data = as_json['resultData'] 27 | # statusCode 14 似乎是表示延期到帐的意思, 如: 签到成功,钢镚将于15个工作日内发放到账 28 | sign_success = result_data['isSuccess'] or result_data['statusCode'] == 14 29 | message = result_data['showMsg'] 30 | 31 | # 参见 daka_app_min.js, 第 1893 行 32 | continuity_days = result_data['continuityDays'] 33 | 34 | if continuity_days > 1: 35 | message += '; 签到天数: {}'.format(continuity_days) 36 | 37 | else: 38 | sign_success = False 39 | message = as_json.get('resultMsg') or as_json.get('resultMessage') 40 | 41 | logging.info('打卡成功: {}; Message: {}'.format(sign_success, message)) 42 | 43 | return sign_success 44 | 45 | # 46 | # def get_sign_data(self): 47 | # payload = { 48 | # 'reqData': '{"clientType":"outH5","userType":41,"groupType":154}', 49 | # 'sid': self.session.cookies.get('sid'), 50 | # 'source': 'jrm' 51 | # } 52 | # 53 | # sign_data = {} 54 | # 55 | # try: 56 | # r = self.session.post(self.test_url, data=payload, verify=False) 57 | # as_json = r.json() 58 | # 59 | # if 'resultData' in as_json: 60 | # sign_data = r.json()['resultData']['53'] 61 | # 62 | # else: 63 | # error_msg = as_json.get('resultMsg') or as_json.get( 64 | # 'resultMessage') 65 | # logging.error('获取打卡数据失败: {}'.format(error_msg)) 66 | # 67 | # except Exception as e: 68 | # logging.error('获取打卡数据失败: {}'.format(e)) 69 | # 70 | # return sign_data 71 | # 72 | # def is_signed(self): 73 | # sign_data = self.sign_data or self.get_sign_data() 74 | # 75 | # signed = False 76 | # 77 | # try: 78 | # signed = sign_data['signInStatus'] == 1 79 | # logging.info('今日已打卡: {}'.format(signed)) 80 | # 81 | # except Exception as e: 82 | # logging.error('返回数据结构可能有变化, 获取打卡数据失败: {}'.format(e)) 83 | # 84 | # return signed 85 | -------------------------------------------------------------------------------- /app/utils/comment.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | ''' 3 | 京东订单自动评价 4 | ''' 5 | import json 6 | import logging 7 | import random 8 | import sys 9 | import time 10 | from urllib import parse 11 | 12 | import requests 13 | from furl import furl 14 | from requests_html import HTML 15 | 16 | from app.utils.base import base 17 | 18 | logger = logging.getLogger('jd.comment') 19 | 20 | 21 | class Comment(base): 22 | COMMENT_PATH = './data/comment.txt' 23 | COMMENT_PRODUCT_LIST = 'https://club.jd.com/myJdcomments/myJdcomment.action?sort=%d&page=%d' 24 | PRODUCT_COMMENT_LIST_URL = 'https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv658&productId=%d&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1' 25 | comment_list = None 26 | req_headers = { 27 | 'User-Agen': 28 | 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36', 29 | 'Content-Type': 'application/x-www-form-urlencoded', 30 | 'Accept-Encoding': 'gzip, deflate, br', 31 | 'Accept-Language': 'zh-CN,zh;q=0.9', 32 | 'Accept': 'application/json, text/javascript, */*; q=0.01', 33 | 'Referer': 34 | 'https://club.jd.com/myJdcomments/orderVoucher.action?ruleid=76988862343', 35 | 'X-Requested-With': 'XMLHttpRequest' 36 | } 37 | sort = 0 38 | 39 | def __init__(self): 40 | super(Comment, self).__init__() 41 | if self.comment_list is None: 42 | self.comment_list = self.get_comment_list() 43 | 44 | self.load_cookie() 45 | 46 | def get_product_list(self, page=1): 47 | url = self.COMMENT_PRODUCT_LIST % (int(self.sort), int(page)) 48 | try: 49 | result = self.session.get(url, verify=False) 50 | except Exception as e: 51 | logging.exception(e) 52 | return False 53 | 54 | return self.parse_product_list(result.text) 55 | 56 | def start_comment(self): 57 | if self.sort == 0: 58 | comment_type = '订单评价' 59 | elif self.sort == 1: 60 | comment_type = '晒单评价' 61 | elif self.sort == 3: 62 | comment_type = '追加评价' 63 | elif self.sort == 4: 64 | comment_type = '服务评价' 65 | page = 1 66 | while 1: 67 | product_list = self.get_product_list(page) 68 | if not product_list and page == 1: 69 | logging.info(comment_type + '评价完成') 70 | return True 71 | elif not product_list: 72 | page = 1 73 | continue 74 | else: 75 | page += 1 76 | 77 | # TODO: 测试代码 78 | # self.getSkuInstallVoucherByOrderId('102750366961') 79 | # sys.exit() 80 | logger.info('获取未评价订单数: {}'.format(len(product_list))) 81 | 82 | for i in product_list: 83 | if self.sort == 4: 84 | result = self.submit_comment(i.get('order_id')) 85 | if self.sort == 0: 86 | result = self.submit_comment(i.get('order_id'), 87 | i.get('product_id')) 88 | if self.sort == 3: 89 | result = self.submit_comment(i.get('order_id'), 90 | i.get('product_id')) 91 | 92 | if result: 93 | logger.info('【%s成功】 订单id: %d, 商品id: %d' % 94 | (comment_type, int(i.get('order_id')), 95 | int(i.get('product_id')))) 96 | else: 97 | logger.info('【%s失败】可能已评价过订单 订单id: %d, 商品id: %d' % 98 | (comment_type, int(i.get('order_id')), 99 | int(i.get('product_id')))) 100 | time.sleep(5) 101 | 102 | def get_comment_list(self): 103 | with open(self.COMMENT_PATH, 'r', encoding='UTF-8') as f: 104 | data = f.read() 105 | 106 | return list(filter(None, data.split("\n"))) 107 | 108 | def getProductCommentImgList(self, product_id): 109 | url = self.PRODUCT_COMMENT_LIST_URL % (int(product_id)) 110 | try: 111 | result = requests.get(url, verify=False) 112 | except Exception as e: 113 | logging.exception(e) 114 | return False 115 | 116 | data = result.text.replace('fetchJSON_comment98vv658(', 117 | '').replace(');', '') 118 | images = [] 119 | if data: 120 | data = json.loads(data) 121 | for i in data['comments']: 122 | if i.get('images'): 123 | for _images in i.get('images'): 124 | images.append(_images.get('imgUrl')) 125 | if len(images) >= 3: 126 | break 127 | 128 | return images 129 | 130 | 131 | class ServerComment(Comment): 132 | ''' 133 | 服务评价 134 | ''' 135 | COMMENT_URL = 'https://club.jd.com/myJdcomments/insertRestSurvey.action?voteid=145&ruleid=%d' 136 | 137 | def __init__(self): 138 | super(ServerComment, self).__init__() 139 | self.sort = 4 140 | 141 | def parse_product_list(self, html): 142 | html = HTML(html=html) 143 | tbody_list = html.find( 144 | '#main > div.mycomment-bd > div.mycomment-table > table > tbody') 145 | lists = [] 146 | for _tbody in tbody_list: 147 | _tbody = HTML(html=_tbody.html) 148 | product_url = furl( 149 | _tbody.find( 150 | 'tr.tr-bd > td:nth-child(1) > div.goods-item > div.p-msg > div > a' 151 | )[0].attrs['href']) 152 | order_id = _tbody.find('tr.tr-th > td > span.number > a')[0].text 153 | lists.append({ 154 | 'product_id': 155 | int(str(product_url.path).strip('/').strip('.html')), 156 | 'order_id': 157 | order_id 158 | }) 159 | return lists 160 | 161 | def getSkuInstallVoucherByOrderId(self, order_id): 162 | url = 'https://club.jd.com/myJdcomments/getSkuInstallVoucherByOrderId.action?callback=jQuery7340659&orderId={}&_={}'.format( 163 | order_id, time.time()) 164 | result = self.session.get(url, headers=self.req_headers, verify=False) 165 | logger.debug(result.text) 166 | data = result.text.replace('jQuery7340659(', '').replace(');', '') 167 | data = json.loads(data) 168 | if data.get('success') is True: 169 | voucherList = data.get('result').get('voucherList') 170 | if voucherList: 171 | saveSkuInstallVoucherByOrderIdUrl = 'https://club.jd.com/myJdcomments/saveSkuInstallComment.action' 172 | post_data = { 173 | 'orderId': order_id, 174 | 'pin': voucherList[0].get('pin'), 175 | 'associateId': voucherList[0].get('associateId'), 176 | 'userClient': "2", 177 | 'score1': '1', 178 | 'ip': '192.168.1.1', 179 | 'content': '安装师傅很用心, 很不错, 非常感谢', 180 | } 181 | result = self.session.post(saveSkuInstallVoucherByOrderIdUrl, 182 | data=post_data, 183 | headers=self.req_headers, 184 | verify=False) 185 | data = json.loads(result.text) 186 | if data.get('success') is True: 187 | logger.info('安装服务评价成功, 订单号:{}'.format(order_id)) 188 | return True 189 | else: 190 | logger.info('安装服务评价成功, 可能已评价过, 订单号:{}'.format(order_id)) 191 | return False 192 | 193 | def submit_comment(self, order_id): 194 | ''' 服务评价 ''' 195 | post_data = { 196 | 'oid': order_id, 197 | 'gid': 69, 198 | 'sid': 549656, 199 | 'tags': '', 200 | 'ro1827': '1827A1', 201 | 'ro1828': '1828A1', 202 | 'ro1829': '1829A1' 203 | } 204 | results = self.session.post(self.COMMENT_URL % (int(order_id)), 205 | data=post_data, 206 | headers=self.req_headers, 207 | verify=False) 208 | self.getSkuInstallVoucherByOrderId(order_id) 209 | data = json.loads(results.text) 210 | logger.debug(results.text) 211 | if data.get('success') is True: 212 | logger.info('服务评价成功, 订单号:{}'.format(order_id)) 213 | return results.text 214 | 215 | 216 | class ProductComment(Comment): 217 | COMMENT_URL = 'https://club.jd.com/myJdcomments/saveProductComment.action' 218 | 219 | def __init__(self): 220 | super(ProductComment, self).__init__() 221 | self.sort = 0 222 | 223 | def parse_product_list(self, html): 224 | html = HTML(html=html) 225 | order_list = html.find( 226 | '#main > div.mycomment-bd > div.mycomment-table table tbody') 227 | 228 | list = [] 229 | for _order in order_list: 230 | _product_list = _order.find('tr.tr-bd') 231 | order_id = _order.find('tr.tr-th > td > span.number > a')[0].text 232 | for _product in _product_list: 233 | product_url = furl( 234 | _product.find('div.goods-item > div.p-msg > div.p-name > a' 235 | )[0].attrs['href']) 236 | 237 | list.append({ 238 | 'order_id': 239 | order_id, 240 | 'product_id': 241 | int(str(product_url.path).strip('/').strip('.html')) 242 | }) 243 | return list 244 | 245 | def submit_comment(self, order_id, product_id): 246 | ''' 评价商品 ''' 247 | content = random.sample(self.comment_list, 1)[0] 248 | 249 | comment_tags = self.getProductCommentTag(product_id) 250 | 251 | params = { 252 | 'orderId': order_id, 253 | 'productId': product_id, 254 | 'content': parse.quote(content), 255 | 'imgs': ','.join(self.getProductCommentImgList(product_id)), 256 | 'score': 5, 257 | 'anonymousFlag': 1, 258 | 'saveStatus': 2 259 | } 260 | if comment_tags: 261 | tags = [[str(comment_tags[0]['id']), comment_tags[0]['name']]] 262 | params['tag'] = parse.quote(json.dumps( 263 | tags, 264 | ensure_ascii=False, 265 | )) 266 | 267 | results = self.session.post( 268 | 'https://club.jd.com/myJdcomments/saveProductComment.action', 269 | data=params, 270 | headers=self.req_headers, 271 | verify=False) 272 | results = json.loads(results.text) 273 | 274 | if results.get('success') != True: 275 | logging.warning(results.get('error')) 276 | del params['imgs'] 277 | 278 | results = self.session.post( 279 | 'https://club.jd.com/myJdcomments/saveProductComment.action', 280 | data=params, 281 | headers=self.req_headers, 282 | verify=False) 283 | results = json.loads(results.text) 284 | 285 | if results.get('success') == True: 286 | return True 287 | else: 288 | logging.warning(results.get('error')) 289 | return False 290 | 291 | def getProductCommentTag(self, product_id): 292 | url = 'https://club.jd.com/myJdcomments/getTagCommentsBySkuId.action?callback=jQuery4334469&voucherstatus=0&productId=%d&cateFirst=1320&cateSecond=1585&cateThird=3986&_=%d' % ( 293 | product_id, time.time()) 294 | 295 | try: 296 | result = self.session.get(url, 297 | verify=False, 298 | headers=self.req_headers) 299 | except Exception as e: 300 | logging.exception(e) 301 | return False 302 | 303 | data = result.text.replace('jQuery4334469(', '').replace(');', '') 304 | data = json.loads(data) 305 | if data.get('tagRecommend'): 306 | return data.get('tagRecommend') 307 | 308 | return False 309 | 310 | 311 | class AppendComment(Comment): 312 | def __init__(self): 313 | super(AppendComment, self).__init__() 314 | self.sort = 3 315 | 316 | def parse_product_list(self, html): 317 | html = HTML(html=html) 318 | product_list = html.find( 319 | '#main > div.mycomment-bd > div.mycomment-table > table > tr > td > div > a' 320 | ) 321 | list = [] 322 | for _product in product_list: 323 | _url = furl(_product.attrs['href']) 324 | list.append({ 325 | 'order_id': _url.args['orderId'], 326 | 'product_id': _url.args['sku'] 327 | }) 328 | 329 | return list 330 | 331 | def submit_comment(self, order_id, product_id): 332 | url = 'https://club.jd.com/afterComments/saveAfterCommentAndShowOrder.action' 333 | content = random.sample(self.comment_list, 1)[0] 334 | params = { 335 | 'orderId': order_id, 336 | 'productId': product_id, 337 | 'content': parse.quote(content), 338 | 'imgs': ','.join(self.getProductCommentImgList(product_id)), 339 | 'anonymousFlag': 1, 340 | } 341 | 342 | results = self.session.post(url, 343 | data=params, 344 | headers=self.req_headers, 345 | verify=False) 346 | results = json.loads(results.text) 347 | 348 | if results.get('success') == True: 349 | return True 350 | else: 351 | logging.warning(results) 352 | return False 353 | -------------------------------------------------------------------------------- /app/utils/utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /app/utils/web_browser.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from PyQt5.QtWidgets import QApplication 3 | from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineProfile 4 | from PyQt5.QtCore import QUrl 5 | import sys 6 | 7 | 8 | class WebBrowser(QWebEngineView): 9 | cookies = {} 10 | 11 | def __init__(self, *args, **kwargs): 12 | super(WebBrowser, self).__init__(*args, **kwargs) 13 | 14 | QWebEngineProfile.defaultProfile().cookieStore().cookieAdded.connect( 15 | self.onCookieAdd) 16 | self.loadFinished.connect(self.onLoadFinished) 17 | 18 | def onLoadFinished(self): 19 | return self.cookies 20 | 21 | def onCookieAdd(self, cookie): 22 | ''' 23 | :param cookie: QNetworkCookie 24 | ''' 25 | name = str(cookie.name().data(), encoding='utf-8') 26 | value = str(cookie.value().data(), encoding='utf-8') 27 | 28 | self.cookies[name] = value 29 | 30 | def get_cookies(self): 31 | return self.cookies 32 | 33 | 34 | def openWithWebBrowser(url): 35 | app = QApplication([]) 36 | view = WebBrowser() 37 | view.load(QUrl(url)) 38 | view.show() 39 | app.exec_() 40 | cookies = view.get_cookies() 41 | return cookies 42 | -------------------------------------------------------------------------------- /data/comment.txt: -------------------------------------------------------------------------------- 1 | 商品质量很好,很满意,配送速度快啊,而且配送员态度也非常好。, 2 | 挺好的,非常实用。京东的物流很快哟~希望以后会更快, 3 | 多快好省,京东给力,下次还是要选择京东商城,没错,非常满意, 4 | 非常好,一起买的,价格便宜,快递又快,京东商城还是非常的专业和贴心,可以显示快递的位置,随时掌握快递进度,很先进!, 5 | 活动期间买的很实惠,京东自营,值得信赖。, 6 | 便宜好用,值得推荐买买买,同事都说好用。下次继续买买买,哈哈哈…, 7 | 京东物流就是一个字快,昨晚10点多,11点前下的单今天早上就收到,包装得很好。, 8 | 京东购物使我们的生活更便捷了!京东商品丰富,无所不有,自营商品更是价格优惠,童叟无欺。快递给力,包装实在。体验足不出户购物的感觉,就在京东!购物就上京东,有京东,足够!, 9 | 一直上京东商城网购,东西非常不错,价格便宜,物流快,是正品, 10 | 质量很好,性价比高,值得购买,送货速度快!!, 11 | 怒赞!(此评论虽仅有两个字,可谓言简意赅,一字千金,字字扣人心弦,催人泪下,足可见评论人扎实的文字功底和信手拈来的写作技巧,再加上以感叹号收尾,点睛之笔,妙笔生花,意境深远,把评论人的感情表达得淋漓尽致,有浑然天成之感,实乃评论中之极品,祝福中之绝笔也) 12 | -------------------------------------------------------------------------------- /data/cookie copy.txt: -------------------------------------------------------------------------------- 1 | {"shshshfpb":"lGhvXDehBvv6cliXmblpk5g^%^3D^%^3D", 2 | "shshshfpa":"e082243d-ae48-81bf-a8b4-ab5135c0da08-1571463172", 3 | "__jdu":"15714631737751222020177", 4 | "user-key":"be81de39-550f-45cb-ab26-fc3703d74cbe", 5 | "areaId":"20", 6 | "ipLoc-djd":"20-1715-3650-43209.1826684983", 7 | "__jdv":"227587231^%^7Cweixin^%^7Ct_1000072672_17053_001^%^7Cweixin^%^7C-^%^7C1571468581018", 8 | "TrackID":"1iuc4DkAsuqG7neLNG9hpAhUs1RjvTxIDYm0TPd1N9EsB_DGzMj4Je4WulCWZGgBlTxdGcRdozTCA0UyOzFW6JyQ4eF6RUECv-87Sobm0Lws", 9 | "pinId":"d1SKiAcg0sxNZaxtdB9fRA", 10 | "pin":"452525ZMD885", 11 | "unick":"452525ZMD885", 12 | "ceshi3.com":"000", 13 | "_tp":"wdfgd0JVI3ekN56WGlfQXA^%^3D^%^3D", 14 | "_pst":"452525ZMD885", 15 | "3AB9D23F7A4B3C9B":"O3CFHXX7PKG5EMGAM527R625HNFKDLZ735R2QJEH2QQUM7GUHTIU36G6PLN4Z72WMSEG2PUH2MSUXOKSVGB4HFGDGU", 16 | "mba_muid":"15714631737751222020177", 17 | "TrackerID":"g21-V_7MNEZCR0FNIVdl95W6fIHUvXN1oR-To0EPer9eyCQF1NAOkhwnunxF9_TcKvwJ6T21oQMBIBa0_1whOSdfyz_IJONG3l07CwJVy0M", 18 | "pt_key":"AAJdqwW9ADABzIc6A_uIlpC_21SXlnXhjXrUzoYybC6wveWABjHr4FUXK3zYT26D5a0U_dd9i-k", 19 | "pt_pin":"452525ZMD885", 20 | "pt_token":"zrd46d7r", 21 | "pwdt_id":"452525ZMD885", 22 | "wxa_level":"1", 23 | "retina":"0", 24 | "webp":"1", 25 | "visitkey":"52264883070895550", 26 | "PPRD_P":"UUID.15714631737751222020177", 27 | "sc_width":"1920", 28 | "buy_uin":"21632141358", 29 | "jdpin":"452525ZMD885", 30 | "wq_skey":"zm31A9221DB04992C84E9531E32312F68AE2BD4A78D4513ED2483311F9E04742E080A9D66AA96ACDA2468E2A8CF2D763EB4BF7CC9B6F30EB0E1FEBA938512EED14696209914936E0E0BD67BE46DF19457A", 31 | "wq_uin":"21632141358", 32 | "cid":"9", 33 | "__wga":"1571489335738.1571489214810.1571489214810.1571489214810.5.1", 34 | "__jdc":"122270672", 35 | "__jda":"122270672.15714631737751222020177.1571463173.1571489040.1571492373.8", 36 | "cn":"89", 37 | "shshshfp":"9fa78c260596ce91f9b4fe13478dc3a1", 38 | "shshshsID":"e99fa356008caab33c3a4cf49bac919d_1_1571492412125", 39 | "thor":"B1FF1CDB0696D50AE89A570D8FBD93104C6F97123FDF682D2E5E701406DB3C480D9ACAB4F4D8FD3A490F0A4BC11C73037BA0C2B828CC9F4F6443E7CCCEAF1F38DDF94030CF86A5598B0F8F527874345D32161565F222E36E3D5CECF388EBC80B38D083F3CEE0A09E35ADCE020C2519CACA58218B41349E0DDA59697ED4B1ACB9E2172A49A364FEB3284FD8BBBA0E04A2", 40 | "__jdb":"122270672.26.15714631737751222020177^|8.1571492373"} -------------------------------------------------------------------------------- /data/jd.log: -------------------------------------------------------------------------------- 1 | 2019-10-20 15:08:41,152 - root - INFO - aaaa 2 | 2019-10-20 16:21:54,906 - root - INFO - 登录成功 3 | 2019-10-20 16:21:55,878 - jd.comment - INFO - 获取未评价订单数: 20 4 | 2019-10-20 16:22:22,883 - root - INFO - 登录成功 5 | 2019-10-20 16:22:23,301 - jd.comment - INFO - 获取未评价订单数: 20 6 | 2019-10-20 16:22:56,649 - root - INFO - 登录成功 7 | 2019-10-20 16:22:57,087 - jd.comment - INFO - 获取未评价订单数: 20 8 | 2019-10-20 16:22:57,271 - root - INFO - 【服务评价成功】 订单id: 105848863355, 商品id: 100002580124 9 | 2019-10-20 16:23:02,505 - root - INFO - 【服务评价成功】 订单id: 105250476642, 商品id: 6963418 10 | 2019-10-20 16:25:01,391 - root - INFO - 登录成功 11 | 2019-10-20 16:25:01,821 - jd.comment - INFO - 获取未评价订单数: 20 12 | 2019-10-20 16:25:02,012 - root - INFO - 【服务评价成功】 订单id: 105867938712, 商品id: 100002580124 13 | 2019-10-20 16:25:07,220 - root - INFO - 【服务评价成功】 订单id: 105256707564, 商品id: 8615274 14 | 2019-10-20 16:25:12,426 - root - INFO - 【服务评价成功】 订单id: 105846943227, 商品id: 100008494476 15 | 2019-10-20 16:25:34,908 - root - INFO - 登录成功 16 | 2019-10-20 16:25:35,317 - jd.comment - INFO - 获取未评价订单数: 20 17 | 2019-10-20 16:25:35,514 - root - INFO - 【服务评价成功】 订单id: 105862099228, 商品id: 100002580124 18 | 2019-10-20 16:25:40,710 - root - INFO - 【服务评价成功】 订单id: 105845685659, 商品id: 8172248 19 | 2019-10-20 16:27:06,481 - root - INFO - 登录成功 20 | 2019-10-20 16:27:06,899 - jd.comment - INFO - 获取未评价订单数: 20 21 | 2019-10-20 16:27:07,078 - jd.comment - INFO - 【服务评价成功】 订单id: 105852773393, 商品id: 7586379 22 | 2019-10-20 16:27:14,429 - jd.comment - INFO - 【服务评价成功】 订单id: 105245663851, 商品id: 100004169714 23 | 2019-10-20 16:27:19,801 - jd.comment - INFO - 安装服务评价成功, 订单号:104640953952 24 | 2019-10-20 16:27:19,801 - jd.comment - INFO - 【服务评价成功】 订单id: 104640953952, 商品id: 100003481172 25 | 2019-10-20 16:27:24,999 - jd.comment - INFO - 【服务评价成功】 订单id: 105246148485, 商品id: 100004188730 26 | 2019-10-20 16:27:30,184 - jd.comment - INFO - 【服务评价成功】 订单id: 105850585652, 商品id: 100004188730 27 | 2019-10-20 16:27:35,390 - jd.comment - INFO - 【服务评价成功】 订单id: 105246507565, 商品id: 100004188730 28 | 2019-10-20 16:44:51,019 - root - INFO - 服务评价评价完成 29 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | import requests 3 | import logging 4 | import click 5 | from app.utils.base import Login 6 | from app.utils.comment import ServerComment, ProductComment, AppendComment 7 | from app.utils.bean_app import bean_app as bean_app_shell 8 | from app.utils.bean_vip import bean_vip as bean_vip_shell 9 | from app.utils.clock_app import clock_app as clock_app_shell 10 | from app.utils.clock import clock as clock_shell 11 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 12 | requests.packages.urllib3.disable_warnings(InsecureRequestWarning) # 禁用安全请求警告 13 | 14 | logging.basicConfig( 15 | level=logging.INFO, 16 | format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', 17 | filemode='a', 18 | filename='data/jd.log') 19 | 20 | logger = logging.getLogger() 21 | 22 | console_handler = logging.StreamHandler() 23 | logger.addHandler(console_handler) 24 | 25 | 26 | @click.group() 27 | def cli(): 28 | pass 29 | 30 | 31 | @click.command() 32 | def comment(): 33 | login_result = Login().login() 34 | if login_result: 35 | logging.info('登录成功') 36 | 37 | # 服务评价 38 | ServerComment().start_comment() 39 | # 商品评价 40 | # ProductComment().start_comment() 41 | # 追加评价 42 | # AppendComment().start_comment() 43 | 44 | 45 | @click.command() 46 | def bean_app(): 47 | login_result = Login().login() 48 | if login_result: 49 | logging.info('登录成功') 50 | 51 | bean_app_shell().run() 52 | 53 | 54 | @click.command() 55 | def bean_vip(): 56 | login_result = Login().login() 57 | if login_result: 58 | logging.info('登录成功') 59 | 60 | bean_vip_shell().run() 61 | 62 | 63 | @click.command() 64 | def clock_app(): 65 | login_result = Login().login() 66 | if login_result: 67 | logging.info('登录成功') 68 | 69 | clock_app_shell().run() 70 | 71 | 72 | @click.command() 73 | def clock(): 74 | login_result = Login().login() 75 | if login_result: 76 | logging.info('登录成功') 77 | 78 | clock_shell().run() 79 | 80 | 81 | cli.add_command(comment) 82 | cli.add_command(bean_app) 83 | cli.add_command(bean_vip) 84 | cli.add_command(clock_app) 85 | cli.add_command(clock) 86 | if __name__ == '__main__': 87 | cli() 88 | --------------------------------------------------------------------------------