├── AutomationTool ├── 12306-login │ ├── 12306.py │ ├── README.md │ └── chaojiying.py └── bilibili-login │ ├── README.md │ └── bilibili.py ├── BasicTraining ├── anjuke │ ├── README.md │ └── anjuke.py ├── douban-top250 │ ├── README.md │ └── douban.py ├── guazi │ ├── README.md │ └── guazi.py ├── hupu │ ├── README.md │ └── hupu.py └── maoyan-top100 │ ├── README.md │ └── maoyan.py ├── CommentPlugin ├── facebook-comments │ ├── README.md │ ├── facebook.py │ └── facebook_comments.json └── vuukle-comments │ ├── README.md │ ├── vuukle.py │ └── vuukle_comments.json ├── FightAgainstSpider └── 58tongcheng │ ├── 58tongcheng.py │ └── README.md ├── JSReverse ├── account_xiaomi_com │ └── xiaomi_login.py ├── d_weidian_com │ ├── get_encrypted_ua.js │ ├── uad.js │ ├── uad_reduction.js │ └── weidian_login.py ├── dict_cnki_net │ ├── cnki.py │ └── cnki_encrypt.js ├── epay_163_com │ └── epay.js ├── etherrock_ne │ ├── airdrop_submit.py │ └── get_content_and_key.js ├── fanyi_baidu_com │ ├── baidu_encrypt.js │ └── baidufanyi.py ├── fanyi_youdao_com │ ├── youdao_encrypt.js │ └── youdaofanyi.py ├── fuwu_nhsa_gov_cn │ ├── nhsa.js │ └── nhsa.py ├── i_360_cn │ ├── 360_encrypt.js │ ├── 360_login.py │ └── code.png ├── jzsc_mohurd_gov_cn │ ├── jzsc_mohurd.py │ └── jzsc_mohurd_decrypt.js ├── learn_open_com_cn │ ├── fm_new.js │ ├── fm_old.js │ ├── get_black_box.js │ ├── open_login.py │ └── replace_js.py ├── login_189_cn │ ├── 189_encrypt.js │ ├── 189_login.py │ └── code.png ├── login_flyme_cn │ ├── flyme_encrypt.js │ └── flyme_login.py ├── m_wcbchina_com │ ├── wcbchina_encrypt.js │ └── wcbchina_login.py ├── max_pedata_cn │ ├── main.py │ └── pedata_decrypt.js ├── oauth_d_cn │ ├── d_cn_encrypt.js │ └── d_cn_login.py ├── passport_fang_com │ ├── fang_encrypt.js │ └── fang_login.py ├── passport_hqew_com │ ├── hqew_encrypt.js │ └── hqew_login.py ├── passport_xueyiyun_com │ ├── xueyiyun_encrypt.js │ └── xueyiyun_login.py ├── passport_yhd_com │ ├── yhd_encrypt.js │ └── yhd_login.py ├── passport_zhihuishu_com │ ├── code.png │ └── zhihuishu_login.py ├── spider_wangluozhe_com_challenge_1 │ ├── challenge_1.js │ └── challenge_1.py ├── spider_wangluozhe_com_challenge_2 │ ├── challenge_2.js │ └── challenge_2.py ├── spider_wangluozhe_com_challenge_3 │ ├── challenge_3.js │ └── challenge_3.py ├── spider_wangluozhe_com_challenge_4 │ ├── challenge_4.js │ └── challenge_4.py ├── spider_wangluozhe_com_challenge_6 │ ├── challenge_6.js │ └── challenge_6.py ├── store_steampowered_com │ ├── code.png │ ├── steampowered_encrypt.js │ └── steampowered_login.py ├── tenhou_net │ ├── tenhou.py │ └── tenhou_decrypt.js ├── tianaw_95505_cn │ ├── tianaw_95505_encrypt.js │ └── tianaw_95505_login.py ├── uac_10010_com │ ├── 10010_encrypt.js │ ├── 10010_login.py │ └── code.png ├── uis_nbu_edu_cn │ ├── code.png │ ├── uis_nbu_encrypt.js │ └── uis_nbu_login.py ├── unicom_trip_133_cn │ ├── unicom_trip.py │ └── unicom_trip_decrypt.js ├── wap_10086_cn │ ├── 10086_encrypt.js │ └── 10086_login.py ├── web_ewt360_com │ ├── ewt360_encrypt.js │ └── ewt360_login.py ├── weibo_com │ ├── weibo_encrypt.js │ └── weibo_login.py ├── www_15yunmall_com │ ├── 15yunmall_encrypt.js │ ├── 15yunmall_login.py │ └── code.png ├── www_37_com │ ├── 37_encrypt.js │ └── 37_login.py ├── www_airasia_com │ └── flightstatus.py ├── www_appmiu_com │ └── appmiu.js ├── www_aqistudy_cn │ ├── main.js │ └── main.py ├── www_gm99_com │ ├── code.png │ ├── gm99_encrypt.js │ ├── gm99_encrypt_2.js │ └── gm99_login.py ├── www_hfax_com │ ├── code.png │ ├── hfax_encrypt.js │ └── hfax_login.py ├── www_hnzwfw_gov_cn │ ├── encrypt.js │ └── hnzww_login.py ├── www_iappstoday_com │ ├── iappstoday_encrypt.js │ └── iappstoday_login.py ├── www_kuwo_cn │ ├── get_reqId.js │ ├── get_reqId_2.js │ ├── get_reqId_3.js │ └── kuwo_search.py ├── www_lagou_com │ ├── lagou.js │ └── main.py ├── www_miguvideo_com │ ├── miguvideo_encrypt.js │ └── miguvideo_login.py ├── www_qimingpian_cn │ ├── qimingpian.py │ └── qimingpian_decrypt.js ├── www_xinshangmeng_com │ └── README.md ├── xueqiu_com │ ├── get_acw_sc_v2.js │ └── main.py └── zwfw_san-he_gov_cn │ ├── zwfw_san_he.py │ └── zwfw_san_he_encrypt.js ├── Material └── 手机UA,累计18428条.txt ├── README.md ├── SignIn └── csdn-sign-in │ ├── CSDN_1.py │ ├── CSDN_2.py │ └── README.md ├── SpiderDataVisualization ├── 51job │ ├── README.md │ ├── draw_bar_chart.py │ ├── get_51job_data.py │ ├── wages_education_chart.png │ └── wages_experience_chart.png └── COVID-19 │ ├── COVID-19-China.xlsx │ ├── COVID-19-Global.xlsx │ ├── COVID-19.html │ ├── README.md │ ├── WordCloud-China.png │ ├── WordCloud-Global.png │ ├── data_get.py │ ├── data_map.py │ ├── data_wordcloud.py │ └── main.py └── image ├── chat.png └── spider_skill.png /AutomationTool/12306-login/12306.py: -------------------------------------------------------------------------------- 1 | # ============================================= 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2019-10-21 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: 12306.py 8 | # @Software: PyCharm 9 | # ============================================= 10 | 11 | import time 12 | from io import BytesIO 13 | from PIL import Image 14 | from selenium import webdriver 15 | from selenium.webdriver.chrome.options import Options 16 | from selenium.webdriver import ActionChains 17 | from selenium.webdriver.common.by import By 18 | from selenium.webdriver.support.ui import WebDriverWait 19 | from selenium.webdriver.support import expected_conditions as EC 20 | from chaojiying import ChaojiyingClient 21 | from selenium.common.exceptions import TimeoutException 22 | 23 | # 12306账号密码 24 | USERNAME = '155********' 25 | PASSWORD = '***********' 26 | 27 | # 超级鹰打码平台账号密码 28 | CHAOJIYING_USERNAME = '********' 29 | CHAOJIYING_PASSWORD = '********' 30 | 31 | # 超级鹰打码平台软件ID 32 | CHAOJIYING_SOFT_ID = '*****' 33 | # 验证码类型 34 | CHAOJIYING_KIND = '9004' 35 | 36 | 37 | class CrackTouClick(): 38 | def __init__(self): 39 | self.url = 'https://kyfw.12306.cn/otn/resources/login.html' 40 | # path是谷歌浏览器驱动的目录,如果已经将目录添加到系统变量,则不用设置此路径 41 | path = r'F:\PycharmProjects\Python3爬虫\chromedriver.exe' 42 | chrome_options = Options() 43 | chrome_options.add_argument('--start-maximized') 44 | self.browser = webdriver.Chrome(executable_path=path, chrome_options=chrome_options) 45 | self.wait = WebDriverWait(self.browser, 20) 46 | self.username = USERNAME 47 | self.password = PASSWORD 48 | self.chaojiying = ChaojiyingClient(CHAOJIYING_USERNAME, CHAOJIYING_PASSWORD, CHAOJIYING_SOFT_ID) 49 | 50 | def crack(self): 51 | # 调用账号密码输入函数 52 | self.get_input_element() 53 | # 调用验证码图片剪裁函数 54 | image = self.get_touclick_image() 55 | bytes_array = BytesIO() 56 | image.save(bytes_array, format='PNG') 57 | # 利用超级鹰打码平台的 API PostPic() 方法把图片发送给超级鹰后台,发送的图像是字节流格式,返回的结果是一个JSON 58 | result = self.chaojiying.PostPic(bytes_array.getvalue(), CHAOJIYING_KIND) 59 | print(result) 60 | # 调用验证码坐标解析函数 61 | locations = self.get_points(result) 62 | # 调用模拟点击验证码函数 63 | self.touch_click_words(locations) 64 | # 调用模拟点击登录函数 65 | self.login() 66 | try: 67 | # 查找是否出现用户的姓名,若出现表示登录成功 68 | success = self.wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, '.welcome-name'), '谭先生')) 69 | print(success) 70 | cc = self.browser.find_element(By.CSS_SELECTOR, '.welcome-name') 71 | print('用户' + cc.text + '登录成功') 72 | # 若没有出现表示登录失败,继续重试,超级鹰会返回本次识别的分值 73 | except TimeoutException: 74 | self.chaojiying.ReportError(result['pic_id']) 75 | self.crack() 76 | 77 | # 账号密码输入函数 78 | def get_input_element(self): 79 | # 登录页面发送请求 80 | self.browser.get(self.url) 81 | # 登录页面默认是扫码登录,所以首先要点击账号登录 82 | login = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.login-hd-account'))) 83 | login.click() 84 | time.sleep(3) 85 | # 查找到账号密码输入位置的元素 86 | username = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input#J-userName'))) 87 | password = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input#J-password'))) 88 | # 输入账号密码 89 | username.send_keys(self.username) 90 | password.send_keys(self.password) 91 | 92 | # 验证码图片剪裁函数 93 | def get_touclick_image(self, name='12306.png'): 94 | # 获取验证码的位置 95 | element = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.login-pwd-code'))) 96 | time.sleep(3) 97 | location = element.location 98 | size = element.size 99 | top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size[ 100 | 'width'] 101 | # 先对整个页面截图 102 | screenshot = self.browser.get_screenshot_as_png() 103 | screenshot = Image.open(BytesIO(screenshot)) 104 | # 根据验证码坐标信息,剪裁出验证码图片 105 | captcha = screenshot.crop((left, top, right, bottom)) 106 | captcha.save(name) 107 | return captcha 108 | 109 | # 验证码坐标解析函数,分析超级鹰返回的坐标 110 | def get_points(self, captcha_result): 111 | # 超级鹰识别结果以字符串形式返回,每个坐标都以|分隔 112 | groups = captcha_result.get('pic_str').split('|') 113 | # 将坐标信息变成列表的形式 114 | locations = [[int(number) for number in group.split(',')] for group in groups] 115 | return locations 116 | 117 | # 模拟点击验证码函数 118 | def touch_click_words(self, locations): 119 | element = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.login-pwd-code'))) 120 | # 循环点击正确验证码的坐标 121 | for location in locations: 122 | print(location) 123 | ActionChains(self.browser).move_to_element_with_offset(element, location[0], location[1]).click().perform() 124 | 125 | # 模拟点击登录函数 126 | def login(self): 127 | submit = self.wait.until(EC.element_to_be_clickable((By.ID, 'J-login'))) 128 | submit.click() 129 | 130 | 131 | if __name__ == '__main__': 132 | crack = CrackTouClick() 133 | crack.crack() 134 | -------------------------------------------------------------------------------- /AutomationTool/12306-login/README.md: -------------------------------------------------------------------------------- 1 | - ## 模拟登陆12306 2 | 3 | - 登录时间:2019-10-21 4 | 5 | - 实现难度:★★★☆☆☆ 6 | 7 | - 请求链接:https://kyfw.12306.cn/otn/resources/login.html 8 | 9 | - 实现目标:模拟登陆中国铁路12306,攻克点触验证码 10 | 11 | - 涉及知识:点触验证码的攻克、自动化测试工具 Selenium 的使用、对接在线打码平台 12 | 13 | - CSDN 链接:https://itrhx.blog.csdn.net/article/details/102662630 14 | 15 | - 个人博客链接:https://www.itrhx.com/2019/10/21/A57-pyspider-12306-login/ 16 | 17 | - 效果截图:(关键信息已经过打码处理) 18 | 19 | ![02](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A57/12306.gif) 20 | -------------------------------------------------------------------------------- /AutomationTool/12306-login/chaojiying.py: -------------------------------------------------------------------------------- 1 | # ============================================= 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2019-10-21 4 | # @Blog : www.itrhx.com 5 | # @CSDN : itrhx.blog.csdn.net 6 | # @FileName: chaojiying.py 7 | # @Software: PyCharm 8 | # ============================================= 9 | 10 | 11 | import requests 12 | from hashlib import md5 13 | 14 | 15 | class ChaojiyingClient(object): 16 | def __init__(self, username, password, soft_id): 17 | self.username = username 18 | password = password.encode('utf8') 19 | self.password = md5(password).hexdigest() 20 | self.soft_id = soft_id 21 | self.base_params = { 22 | 'user': self.username, 23 | 'pass2': self.password, 24 | 'softid': self.soft_id, 25 | } 26 | self.headers = { 27 | 'Connection': 'Keep-Alive', 28 | 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)', 29 | } 30 | 31 | def PostPic(self, im, codetype): 32 | """ 33 | im: 图片字节 34 | codetype: 题目类型 参考 http://www.chaojiying.com/price.html 35 | """ 36 | params = { 37 | 'codetype': codetype, 38 | } 39 | params.update(self.base_params) 40 | files = {'userfile': ('ccc.jpg', im)} 41 | r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers) 42 | return r.json() 43 | 44 | def ReportError(self, im_id): 45 | """ 46 | im_id:报错题目的图片ID 47 | """ 48 | params = { 49 | 'id': im_id, 50 | } 51 | params.update(self.base_params) 52 | r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers) 53 | return r.json() 54 | -------------------------------------------------------------------------------- /AutomationTool/bilibili-login/README.md: -------------------------------------------------------------------------------- 1 | - ## 模拟登陆哔哩哔哩 2 | 3 | - 登录时间:2019-10-21 4 | 5 | - 实现难度:★★★☆☆☆ 6 | 7 | - 请求链接:https://passport.bilibili.com/login 8 | 9 | - 实现目标:模拟登陆哔哩哔哩,攻克滑动验证码 10 | 11 | - 涉及知识:滑动验证码的攻克、自动化测试工具 Selenium 的使用 12 | 13 | - CSDN 链接:https://itrhx.blog.csdn.net/article/details/102649689 14 | 15 | - 个人博客链接:https://www.itrhx.com/2019/10/21/A56-pyspider-bilibili-login/ 16 | 17 | - 效果截图:(关键信息已经过打码处理) 18 | 19 | ![04](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A56/bilibili.gif) 20 | -------------------------------------------------------------------------------- /BasicTraining/anjuke/README.md: -------------------------------------------------------------------------------- 1 | - ## 安居客武汉二手房 2 | 3 | - 爬取时间:2019-10-09 4 | 5 | - 爬取难度:★★☆☆☆☆ 6 | 7 | - 请求链接:https://wuhan.anjuke.com/sale/ 8 | 9 | - 爬取目标:爬取武汉二手房每一条售房信息,包含地理位置、价格、面积等,保存为 CSV 文件 10 | 11 | - 涉及知识:请求库 requests、解析库 Beautiful Soup、CSV 文件储存、列表操作、分页判断 12 | 13 | - CSDN 链接:https://itrhx.blog.csdn.net/article/details/102468535 14 | 15 | - 个人博客链接:https://www.itrhx.com/2019/10/09/A54-pyspider-anjuke/ 16 | 17 | - 效果截图: 18 | 19 | ![03](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A54/03.png) 20 | -------------------------------------------------------------------------------- /BasicTraining/anjuke/anjuke.py: -------------------------------------------------------------------------------- 1 | # ============================================= 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2019-10-09 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: anjuke.py 8 | # @Software: PyCharm 9 | # ============================================= 10 | 11 | import requests 12 | import time 13 | import csv 14 | import random 15 | from bs4 import BeautifulSoup 16 | 17 | headers = { 18 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' 19 | } 20 | 21 | 22 | def parse_pages(url, num): 23 | response = requests.get(url=url, headers=headers) 24 | soup = BeautifulSoup(response.text, 'lxml') 25 | result_list = soup.find_all('li', class_='list-item') 26 | # print(len(result_list)) 27 | for result in result_list: 28 | # 标题 29 | title = result.find('a', class_='houseListTitle').text.strip() 30 | # print(title) 31 | # 户型 32 | layout = result.select('.details-item > span')[0].text 33 | # print(layout) 34 | # 面积 35 | cover = result.select('.details-item > span')[1].text 36 | # print(cover) 37 | # 楼层 38 | floor = result.select('.details-item > span')[2].text 39 | # print(floor) 40 | # 建造年份 41 | year = result.select('.details-item > span')[3].text 42 | # print(year) 43 | # 单价 44 | unit_price = result.find('span', class_='unit-price').text.strip() 45 | # print(unit_price) 46 | # 总价 47 | total_price = result.find('span', class_='price-det').text.strip() 48 | # print(total_price) 49 | # 关键字 50 | keyword = result.find('div', class_='tags-bottom').text.strip() 51 | # print(keyword) 52 | # 地址 53 | address = result.find('span', class_='comm-address').text.replace(' ', '').replace('\n', '') 54 | # print(address) 55 | # 详情页url 56 | details_url = result.find('a', class_='houseListTitle')['href'] 57 | # print(details_url) 58 | results = [title, layout, cover, floor, year, unit_price, total_price, keyword, address, details_url] 59 | with open('anjuke.csv', 'a', newline='', encoding='utf-8-sig') as f: 60 | w = csv.writer(f) 61 | w.writerow(results) 62 | 63 | # 判断是否还有下一页 64 | next_url = soup.find_all('a', class_='aNxt') 65 | if len(next_url) != 0: 66 | num += 1 67 | print('第' + str(num) + '页数据爬取完毕!') 68 | # 3-60秒之间随机暂停 69 | time.sleep(random.randint(3, 60)) 70 | parse_pages(next_url[0].attrs['href'], num) 71 | else: 72 | print('所有数据爬取完毕!') 73 | 74 | 75 | if __name__ == '__main__': 76 | with open('anjuke.csv', 'a', newline='', encoding='utf-8-sig') as fp: 77 | writer = csv.writer(fp) 78 | writer.writerow(['标题', '户型', '面积', '楼层', '建造年份', '单价', '总价', '关键字', '地址', '详情页地址']) 79 | start_num = 0 80 | start_url = 'https://wuhan.anjuke.com/sale/' 81 | parse_pages(start_url, start_num) 82 | -------------------------------------------------------------------------------- /BasicTraining/douban-top250/README.md: -------------------------------------------------------------------------------- 1 | - ## 豆瓣电影 TOP250 2 | 3 | - 爬取时间:2019-09-27 4 | 5 | - 爬取难度:★★☆☆☆☆ 6 | 7 | - 请求链接:https://movie.douban.com/top250 以及每部电影详情页 8 | 9 | - 爬取目标:爬取榜单上每一部电影详情页的数据,保存为 CSV 文件;下载所有电影海报到本地 10 | 11 | - 涉及知识:请求库 requests、解析库 lxml、Xpath 语法、正则表达式、CSV 和二进制数据储存、列表操作 12 | 13 | - CSDN 链接:https://itrhx.blog.csdn.net/article/details/101572275 14 | 15 | - 个人博客链接:https://www.itrhx.com/2019/09/28/A52-pyspider-doubantop250/ 16 | 17 | - 效果截图: 18 | 19 | ![03](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A52/03.png) 20 | 21 | ![04](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A52/04.png) 22 | -------------------------------------------------------------------------------- /BasicTraining/douban-top250/douban.py: -------------------------------------------------------------------------------- 1 | # ============================================= 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2019-09-27 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: douban.py 8 | # @Software: PyCharm 9 | # ============================================= 10 | 11 | import requests 12 | from lxml import etree 13 | import csv 14 | import re 15 | import time 16 | import os 17 | 18 | headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'} 19 | 20 | 21 | def index_pages(number): 22 | url = 'https://movie.douban.com/top250?start=%s&filter=' % number 23 | index_response = requests.get(url=url, headers=headers) 24 | tree = etree.HTML(index_response.text) 25 | m_urls = tree.xpath("//li/div/div/a/@href") 26 | return m_urls 27 | 28 | 29 | def parse_pages(url): 30 | movie_pages = requests.get(url=url, headers=headers) 31 | parse_movie = etree.HTML(movie_pages.text) 32 | 33 | # 排名 34 | ranking = parse_movie.xpath("//span[@class='top250-no']/text()") 35 | 36 | # 电影名 37 | name = parse_movie.xpath("//h1/span[1]/text()") 38 | 39 | # 评分 40 | score = parse_movie.xpath("//div[@class='rating_self clearfix']/strong/text()") 41 | 42 | # 参评人数 43 | value = parse_movie.xpath("//span[@property='v:votes']/text()") 44 | number = [" ".join(['参评人数:'] + value)] 45 | # value = parse_movie.xpath("//a[@class='rating_people']") 46 | # string = [value[0].xpath('string(.)')] 47 | # number = [a.strip() for a in string] 48 | # print(number) 49 | 50 | # 类型 51 | value = parse_movie.xpath("//span[@property='v:genre']/text()") 52 | types = [" ".join(['类型:'] + value)] 53 | 54 | # 制片国家/地区 55 | value = re.findall('制片国家/地区:(.*?)
', movie_pages.text) 56 | country = [" ".join(['制片国家:'] + value)] 57 | 58 | # 语言 59 | value = re.findall('语言:(.*?)
', movie_pages.text) 60 | language = [" ".join(['语言:'] + value)] 61 | 62 | # 上映时期 63 | value = parse_movie.xpath("//span[@property='v:initialReleaseDate']/text()") 64 | date = [" ".join(['上映日期:'] + value)] 65 | 66 | # 片长 67 | value = parse_movie.xpath("//span[@property='v:runtime']/text()") 68 | time = [" ".join(['片长:'] + value)] 69 | 70 | # 又名 71 | value = re.findall('又名:(.*?)
', movie_pages.text) 72 | other_name = [" ".join(['又名:'] + value)] 73 | 74 | # 导演 75 | value = parse_movie.xpath("//div[@id='info']/span[1]/span[@class='attrs']/a/text()") 76 | director = [" ".join(['导演:'] + value)] 77 | 78 | # 编剧 79 | value = parse_movie.xpath("//div[@id='info']/span[2]/span[@class='attrs']/a/text()") 80 | screenwriter = [" ".join(['编剧:'] + value)] 81 | 82 | # 主演 83 | value = parse_movie.xpath("//div[@id='info']/span[3]") 84 | performer = [value[0].xpath('string(.)')] 85 | 86 | # URL 87 | m_url = ['豆瓣链接:' + movie_url] 88 | 89 | # IMDb链接 90 | value = parse_movie.xpath("//div[@id='info']/a/@href") 91 | imdb_url = [" ".join(['IMDb链接:'] + value)] 92 | 93 | # 保存电影海报 94 | poster = parse_movie.xpath("//div[@id='mainpic']/a/img/@src") 95 | response = requests.get(poster[0]) 96 | name2 = re.sub(r'[A-Za-z\:\s]', '', name[0]) 97 | poster_name = str(ranking[0]) + ' - ' + name2 + '.jpg' 98 | dir_name = 'douban_poster' 99 | if not os.path.exists(dir_name): 100 | os.mkdir(dir_name) 101 | poster_path = dir_name + '/' + poster_name 102 | with open(poster_path, "wb")as f: 103 | f.write(response.content) 104 | 105 | return zip(ranking, name, score, number, types, country, language, date, time, other_name, director, screenwriter, performer, m_url, imdb_url) 106 | 107 | 108 | def save_results(data): 109 | with open('douban.csv', 'a', encoding="utf-8-sig") as fp: 110 | writer = csv.writer(fp) 111 | writer.writerow(data) 112 | 113 | 114 | if __name__ == '__main__': 115 | num = 0 116 | for i in range(0, 250, 25): 117 | movie_urls = index_pages(i) 118 | for movie_url in movie_urls: 119 | results = parse_pages(movie_url) 120 | for result in results: 121 | num += 1 122 | save_results(result) 123 | print('第' + str(num) + '条电影信息保存完毕!') 124 | time.sleep(3) 125 | -------------------------------------------------------------------------------- /BasicTraining/guazi/README.md: -------------------------------------------------------------------------------- 1 | - ## 瓜子全国二手车 2 | 3 | - 爬取时间:2019-11-14 4 | 5 | - 爬取难度:★★☆☆☆☆ 6 | 7 | - 请求链接:https://www.guazi.com/www/buy/ 8 | 9 | - 爬取目标:爬取瓜子全国二手车信息,包括价格、上牌时间、表显里程等;保存车辆图片 10 | 11 | - 涉及知识:请求库 requests、解析库 lxml、Xpath 语法、数据库 MongoDB 的操作 12 | 13 | - CSDN 链接:https://itrhx.blog.csdn.net/article/details/103069962 14 | 15 | - 个人博客链接:https://www.itrhx.com/2019/11/15/A59-pyspider-guazi/ 16 | 17 | - 效果截图: 18 | 19 | 爬取的汽车图片: 20 | ![02](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A59/02.png) 21 | 22 | 储存到 MongoDB 的数据: 23 | ![03](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A59/03.png) 24 | 25 | 数据导出为 CSV 文件: 26 | ![04](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A59/04.png) 27 | -------------------------------------------------------------------------------- /BasicTraining/hupu/README.md: -------------------------------------------------------------------------------- 1 | - ## 虎扑论坛步行街 2 | 3 | - 爬取时间:2019-10-12 4 | 5 | - 爬取难度:★★☆☆☆☆ 6 | 7 | - 请求链接:https://bbs.hupu.com/bxj 8 | 9 | - 爬取目标:爬取虎扑论坛步行街的帖子,包含主题,作者,发布时间等,数据保存到 MongoDB 数据库 10 | 11 | - 涉及知识:请求库 requests、解析库 Beautiful Soup、数据库 MongoDB 的操作 12 | 13 | - CSDN 链接:https://itrhx.blog.csdn.net/article/details/102528442 14 | 15 | - 个人博客链接:https://www.itrhx.com/2019/10/12/A55-pyspider-hupu/ 16 | 17 | - 效果截图: 18 | 19 | ![01](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A55/01.png) -------------------------------------------------------------------------------- /BasicTraining/hupu/hupu.py: -------------------------------------------------------------------------------- 1 | # ============================================ 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2019-10-12 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: hupu.py 8 | # @Software: PyCharm 9 | # ============================================ 10 | 11 | import requests 12 | import time 13 | import random 14 | from pymongo import MongoClient 15 | from bs4 import BeautifulSoup 16 | 17 | 18 | def get_pages(page_url): 19 | headers = { 20 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' 21 | } 22 | response = requests.get(url=page_url, headers=headers) 23 | page_soup = BeautifulSoup(response.text, 'lxml') 24 | return page_soup 25 | 26 | 27 | def parse_pages(page_soup): 28 | data_list = [] 29 | all_list = page_soup.find('ul', class_='for-list') 30 | post_list = all_list.find_all('li') 31 | # print(result_list) 32 | for post in post_list: 33 | # 帖子名称 34 | post_title = post.find('a', class_='truetit').text 35 | # print(post_title) 36 | # 帖子链接 37 | post_url = 'https://bbs.hupu.com' + post.find('a', class_='truetit')['href'] 38 | # print(post_url) 39 | # 作者 40 | author = post.select('.author > a')[0].text 41 | # print(author) 42 | # 作者主页 43 | author_url = post.select('.author > a')[0]['href'] 44 | # print(author_url) 45 | # 发布日期 46 | post_date = post.select('.author > a')[1].text 47 | # print(post_date) 48 | reply_view = post.find('span', class_='ansour').text 49 | # 回复数 50 | post_reply = reply_view.split('/')[0].strip() 51 | # print(post_reply) 52 | # 浏览量 53 | post_view = reply_view.split('/')[1].strip() 54 | # print(post_view) 55 | # 最后回复时间 56 | last_data = post.select('.endreply > a')[0].text 57 | # print(last_data) 58 | # 最后回复用户 59 | last_user = post.select('.endreply > span')[0].text 60 | # print(last_user) 61 | 62 | data_list.append([post_title, post_url, author, author_url, post_date, post_reply, post_view, last_data, last_user]) 63 | 64 | # print(data_list) 65 | return data_list 66 | 67 | 68 | def mongodb(data_list): 69 | client = MongoClient('localhost', 27017) 70 | db = client.hupu 71 | collection = db.bxj 72 | for data in data_list: 73 | bxj = { 74 | '帖子名称': data[0], 75 | '帖子链接': data[1], 76 | '作者': data[2], 77 | '作者主页': data[3], 78 | '发布日期': str(data[4]), 79 | '回复数': data[5], 80 | '浏览量': data[6], 81 | '最后回复时间': str(data[7]), 82 | '最后回复用户': data[8] 83 | } 84 | collection.insert_one(bxj) 85 | 86 | 87 | if __name__ == '__main__': 88 | for i in range(1, 11): 89 | url = 'https://bbs.hupu.com/bxj-' + str(i) 90 | soup = get_pages(url) 91 | result_list = parse_pages(soup) 92 | mongodb(result_list) 93 | print('第', i, '页数据爬取完毕!') 94 | time.sleep(random.randint(3, 10)) 95 | print('前10页所有数据爬取完毕!') 96 | -------------------------------------------------------------------------------- /BasicTraining/maoyan-top100/README.md: -------------------------------------------------------------------------------- 1 | - ## 猫眼电影 TOP100 2 | 3 | - 爬取时间:2019-09-23 4 | 5 | - 爬取难度:★☆☆☆☆☆ 6 | 7 | - 请求链接:https://maoyan.com/board/4 8 | 9 | - 爬取目标:猫眼 TOP100 的电影名称、排名、主演、上映时间、评分、封面图地址,数据保存为 CSV 文件 10 | 11 | - 涉及知识:请求库 requests、解析库 lxml、Xpath 语法、CSV 文件储存 12 | 13 | - CSDN 链接:https://itrhx.blog.csdn.net/article/details/101230024 14 | 15 | - 个人博客链接:https://www.itrhx.com/2019/09/24/A51-pyspider-maoyantop100/ 16 | 17 | - 效果截图: 18 | 19 | ![01](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A51/01.png) 20 | -------------------------------------------------------------------------------- /BasicTraining/maoyan-top100/maoyan.py: -------------------------------------------------------------------------------- 1 | # ============================================= 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2019-09-23 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: maoyan.py 8 | # @Software: PyCharm 9 | # ============================================= 10 | 11 | import requests 12 | from lxml import etree 13 | import csv 14 | 15 | headers = { 16 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' 17 | } 18 | 19 | 20 | def index_page(number): 21 | url = 'https://maoyan.com/board/4?offset=%s' % number 22 | response = requests.get(url=url, headers=headers) 23 | return response.text 24 | 25 | 26 | def parse_page(content): 27 | tree = etree.HTML(content) 28 | # 排名 29 | ranking = tree.xpath("//dd/i/text()") 30 | # 电影名称 31 | movie_name = tree.xpath('//p[@class="name"]/a/text()') 32 | # 主演 33 | performer = tree.xpath("//p[@class='star']/text()") 34 | performer = [p.strip() for p in performer] 35 | # 上映时间 36 | releasetime = tree.xpath('//p[@class="releasetime"]/text()') 37 | # 评分 38 | score1 = tree.xpath('//p[@class="score"]/i[@class="integer"]/text()') 39 | score2 = tree.xpath('//p[@class="score"]/i[@class="fraction"]/text()') 40 | score = [score1[i] + score2[i] for i in range(min(len(score1), len(score2)))] 41 | # 电影封面图 42 | movie_img = tree.xpath('//img[@class="board-img"]/@data-src') 43 | # for i in zip(ranking, movie_name, performer, releasetime, score, movie_img): 44 | # print(i) 45 | return zip(ranking, movie_name, performer, releasetime, score, movie_img) 46 | 47 | 48 | def save_results(result): 49 | with open('maoyan.csv', 'a') as fp: 50 | writer = csv.writer(fp) 51 | writer.writerow(result) 52 | 53 | 54 | if __name__ == '__main__': 55 | print('开始爬取数据...') 56 | for i in range(0, 100, 10): 57 | index = index_page(i) 58 | results = parse_page(index) 59 | for i in results: 60 | save_results(i) 61 | print('数据爬取完毕!') 62 | -------------------------------------------------------------------------------- /CommentPlugin/facebook-comments/README.md: -------------------------------------------------------------------------------- 1 | - ## Facebook 评论插件、留言外挂程序采集 2 | 3 | - 实现时间:2021-05-30 4 | 5 | - 实现难度:★★★☆☆☆ 6 | 7 | - 实现目标:采集 Facebook 评论插件、留言外挂程序的所有评论。 8 | 9 | - CSDN 链接:https://itrhx.blog.csdn.net/article/details/117398369 10 | 11 | - Facebook 评论插件官网:https://developers.facebook.com/products/social-plugins/comments 12 | 13 | - 本采集代码适用于 Facebook 评论插件的评论采集。仅用于 Python 编程技术交流! 14 | 15 | - 效果截图: 16 | 17 | ![](https://img-blog.csdnimg.cn/20210530222125607.png) 18 | 19 | ![](https://img-blog.csdnimg.cn/20210530222125750.png) 20 | -------------------------------------------------------------------------------- /CommentPlugin/vuukle-comments/README.md: -------------------------------------------------------------------------------- 1 | - ## Vuukle 评论插件采集 2 | 3 | - 实现时间:2021-05-31 4 | 5 | - 实现难度:★★☆☆☆☆ 6 | 7 | - 实现目标:采集 Vuukle 评论插件的所有评论。 8 | 9 | - Vuukle 评论插件官网:https://vuukle.com/ 10 | 11 | - 本采集代码适用于 Vuukle 评论插件的评论采集。仅用于 Python 编程技术交流! 12 | 13 | - 效果截图: 14 | 15 | ![](https://img-blog.csdnimg.cn/2021053101143820.png) 16 | -------------------------------------------------------------------------------- /CommentPlugin/vuukle-comments/vuukle.py: -------------------------------------------------------------------------------- 1 | # ==================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-05-31 4 | # @Author : TRHX • 鲍勃 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: vuukle.py 8 | # @Software: PyCharm 9 | # ==================================== 10 | 11 | 12 | import re 13 | import json 14 | import random 15 | import requests 16 | from urllib import parse 17 | 18 | 19 | # ============================== 测试链接 ============================== # 20 | # https://newsinfo.inquirer.net/1438710/two-aging-red-leaders-slain 21 | # https://www.manilatimes.net/2021/05/29/opinion/columns/why-grand-plan-to-vaccinate-the-world-vs-covid-unraveled/1801049 22 | # ============================== 测试链接 ============================== # 23 | 24 | 25 | PAGE_URL = 'https://newsinfo.inquirer.net/1438710/two-aging-red-leaders-slain' 26 | PROXIES = {'http': 'http://127.0.0.1:10809', 'https': 'http://127.0.0.1:10809'} 27 | # PROXIES = None # 如果不需要代理则设置为 None 28 | 29 | 30 | class VuukleComment: 31 | def __init__(self): 32 | self.api_key = '' 33 | self.start = 0 34 | self.json_name = 'vuukle_comments.json' 35 | self.host = PAGE_URL.split('/')[2].replace('www.', '') 36 | self.article_id = re.findall(r'/(\d{5,7})', PAGE_URL)[0] 37 | self.comment_api_url = 'https://api.vuukle.com/api/v1/Comments/getCommentFeedBySort?' 38 | 39 | @staticmethod 40 | def find_value_form_html(html: str, key: str, num_chars: int, separator) -> str: 41 | key_begin = html.find(key) + len(key) + num_chars 42 | key_end = html.find(separator, key_begin) 43 | return html[key_begin: key_end] 44 | 45 | @staticmethod 46 | def get_random_ua() -> str: 47 | return "Mozilla/5.0 (Windows NT {}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{} Safari/537.36".format( 48 | random.choice([ 49 | '10.0; Win64; x64', '10.0; WOW64', '10.0', 50 | '6.2; WOW64', '6.2; Win64; x64', '6.2', 51 | '6.1', '6.1; Win64; x64', '6.1; WOW64' 52 | ]), random.choice([ 53 | '70.0.3538.16', '70.0.3538.67', '70.0.3538.97', '71.0.3578.137', '71.0.3578.30', '71.0.3578.33', 54 | '71.0.3578.80', '72.0.3626.69', '72.0.3626.7', '73.0.3683.20', '73.0.3683.68', '74.0.3729.6', 55 | '75.0.3770.140', '75.0.3770.8', '75.0.3770.90', '76.0.3809.12', '76.0.3809.126', '76.0.3809.25', 56 | '76.0.3809.68', '77.0.3865.10', '77.0.3865.40', '78.0.3904.105', '78.0.3904.11', '78.0.3904.70', 57 | '79.0.3945.16', '79.0.3945.36', '80.0.3987.106', '80.0.3987.16', '81.0.4044.138', '81.0.4044.20', 58 | '81.0.4044.69', '83.0.4103.14', '83.0.4103.39', '84.0.4147.30', '85.0.4183.38', '85.0.4183.83', 59 | '85.0.4183.87', '86.0.4240.22', '87.0.4280.20', '87.0.4280.88', '88.0.4324.27' 60 | ])) 61 | 62 | @staticmethod 63 | def save_comment(filename: str, information: json) -> None: 64 | """ 65 | :param filename: 字符串,储存文件名 66 | :param information: JSON,储存的内容 67 | :return: None 68 | """ 69 | with open(filename, 'a+', encoding='utf-8') as f: 70 | f.write(information + '\n') 71 | 72 | def get_app_id(self) -> None: 73 | headers = {'User-Agent': self.get_random_ua()} 74 | response = requests.get(url=PAGE_URL, headers=headers, proxies=PROXIES) 75 | html = response.text 76 | api_key = self.find_value_form_html(html, "apiKey", 3, '"') 77 | self.api_key = api_key 78 | 79 | def get_comment(self) -> None: 80 | flag = True 81 | while flag: 82 | url_parameter = { 83 | 'apiKey': self.api_key, 84 | 'articleId': self.article_id, 85 | 'host': self.host, 86 | 'pageSize': 25, 87 | 'sortBy': 'get_latest', 88 | 'start': self.start 89 | } 90 | comment_url = self.comment_api_url + parse.urlencode(url_parameter) 91 | headers = {'user-agent': self.get_random_ua()} 92 | response = requests.get(url=comment_url, headers=headers, proxies=PROXIES) 93 | comment_dict = json.loads(response.text) 94 | comment_data = comment_dict['data']['comments']['items'] 95 | self.start += comment_dict['data']['comments']['pageSize'] 96 | for comment in comment_data: 97 | print(comment) 98 | self.save_comment(self.json_name, json.dumps(comment, ensure_ascii=False)) 99 | if len(comment_data) != 0: 100 | flag = True 101 | else: 102 | flag = False 103 | 104 | def run(self) -> None: 105 | self.get_app_id() 106 | self.get_comment() 107 | print('\n{} 评论采集完毕!'.format(PAGE_URL)) 108 | 109 | 110 | if __name__ == '__main__': 111 | VC = VuukleComment() 112 | VC.run() 113 | -------------------------------------------------------------------------------- /FightAgainstSpider/58tongcheng/README.md: -------------------------------------------------------------------------------- 1 | - ## 58同城武汉出租房 2 | 3 | - 爬取时间:2019-10-21 4 | 5 | - 爬取难度:★★★☆☆☆ 6 | 7 | - 请求链接:https://wh.58.com/chuzu/ 8 | 9 | - 爬取目标:58同城武汉出租房的所有信息 10 | 11 | - 涉及知识:网站加密字体的攻克、请求库 requests、解析库 Beautiful Soup、数据库 MySQL 的操作 12 | 13 | - CSDN 链接:https://itrhx.blog.csdn.net/article/details/102668128 14 | 15 | - 个人博客链接:https://www.itrhx.com/2019/10/21/A58-pyspider-58tongcheng/ 16 | 17 | - 效果截图: 18 | 19 | ![11](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A58/11.png) 20 | -------------------------------------------------------------------------------- /JSReverse/account_xiaomi_com/xiaomi_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-27 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: xiaomi_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import json 13 | import hashlib 14 | import urllib.parse 15 | 16 | import requests 17 | 18 | 19 | index_url = 'https://account.xiaomi.com/' 20 | login_url = 'https://account.xiaomi.com/pass/serviceLoginAuth2' 21 | headers = { 22 | 'Host': 'account.xiaomi.com', 23 | 'Origin': 'https://account.xiaomi.com', 24 | 'Referer': 'https://account.xiaomi.com/fe/service/login/password?_locale=zh_CN', 25 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 26 | } 27 | session = requests.session() 28 | 29 | 30 | def get_encrypted_password(password): 31 | encrypted_password = hashlib.md5(password.encode(encoding='utf-8')).hexdigest().upper() 32 | return encrypted_password 33 | 34 | 35 | def get_parameter(): 36 | response = requests.get(url=index_url, headers=headers) 37 | location_url = response.history[1].headers['Location'] 38 | urlparse = urllib.parse.urlparse(location_url) 39 | query_dict = urllib.parse.parse_qs(urlparse.query) 40 | # print(query_dict) 41 | return query_dict 42 | 43 | 44 | def login(username, encrypted_password, query_dict): 45 | data = { 46 | 'bizDeviceType': '', 47 | 'needTheme': query_dict['needTheme'][0], 48 | 'theme': '', 49 | 'showActiveX': query_dict['showActiveX'][0], 50 | 'serviceParam': query_dict['serviceParam'][0], 51 | 'callback': query_dict['callback'][0], 52 | 'qs': query_dict['qs'][0], 53 | 'sid': query_dict['sid'][0], 54 | '_sign': query_dict['_sign'][0], 55 | 'user': username, 56 | 'cc': '+86', 57 | 'hash': encrypted_password, 58 | '_json': True 59 | } 60 | response = session.post(url=login_url, data=data, headers=headers) 61 | response_json = json.loads(response.text.replace('&&&START&&&', '')) 62 | print(response_json) 63 | return response_json 64 | 65 | 66 | def main(): 67 | username = input('请输入登录账号: ') 68 | password = input('请输入登录密码: ') 69 | encrypted_password = get_encrypted_password(password) 70 | parameter = get_parameter() 71 | login(username, encrypted_password, parameter) 72 | 73 | 74 | if __name__ == '__main__': 75 | main() 76 | -------------------------------------------------------------------------------- /JSReverse/d_weidian_com/weidian_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-11-15 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: weidian_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | from urllib import parse 15 | 16 | 17 | index_url = "https://d.weidian.com/weidian-pc/pc-vue-index/index.html" 18 | login_url = "https://sso1.weidian.com/user/login" 19 | UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36" 20 | session = requests.session() 21 | 22 | 23 | def get_encrypted_ua(): 24 | with open('get_encrypted_ua.js', 'r', encoding='utf-8') as f: 25 | uad_js = f.read() 26 | ua = execjs.compile(uad_js).call('window.getUa') 27 | ua = parse.quote(ua) 28 | return ua 29 | 30 | 31 | def get_wd_token(): 32 | headers = {"User-Agent": UserAgent} 33 | response = session.get(url=index_url, headers=headers) 34 | wd_token = response.cookies.get_dict()["wdtoken"] 35 | return wd_token 36 | 37 | 38 | def login(phone, password, ua, wd_token): 39 | headers = { 40 | "user-agent": UserAgent, 41 | "origin": "https://d.weidian.com", 42 | "referer": "https://d.weidian.com/", 43 | } 44 | data = { 45 | "phone": phone, 46 | "countryCode": "86", 47 | "password": password, 48 | "version": "1", 49 | "subaccountId": "", 50 | "clientInfo": '{"clientType": 1}', 51 | "captcha_session": "", 52 | "captcha_answer": "", 53 | "vcode": "", 54 | "mediaVcode": "", 55 | "ua": ua, 56 | "scene": "PCLogin", 57 | "wdtoken": wd_token 58 | } 59 | response = session.post(url=login_url, headers=headers, data=data) 60 | print(response.json()) 61 | 62 | 63 | def main(): 64 | phone = input("请输入登录手机号: ") 65 | password = input("请输入登录密码: ") 66 | ua = get_encrypted_ua() 67 | wd_token = get_wd_token() 68 | login(phone, password, ua, wd_token) 69 | 70 | 71 | if __name__ == '__main__': 72 | main() 73 | 74 | -------------------------------------------------------------------------------- /JSReverse/dict_cnki_net/cnki.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-11-05 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: cnki.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | token_url = "https://dict.cnki.net/fyzs-front-api/getToken" 17 | translation_api = "https://dict.cnki.net/fyzs-front-api/translate/literaltranslation" 18 | UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36" 19 | 20 | session = requests.session() 21 | 22 | 23 | def get_token(): 24 | headers = {"User-Agent": UA} 25 | response = session.get(url=token_url, headers=headers).json() 26 | token = response["data"] 27 | return token 28 | 29 | 30 | def get_encrypted_word(word): 31 | with open('cnki_encrypt.js', 'r', encoding='utf-8') as f: 32 | cnki_js = f.read() 33 | encrypted_word = execjs.compile(cnki_js).call('s', word) 34 | return encrypted_word 35 | 36 | 37 | def get_translation_result(encrypted_word, token): 38 | payload = { 39 | "translateType": None, 40 | "words": encrypted_word 41 | } 42 | headers = { 43 | "Token": token, 44 | "User-Agent": UA 45 | } 46 | response = session.post(url=translation_api, headers=headers, json=payload).json() 47 | result = response["data"]["mResult"] 48 | return result 49 | 50 | 51 | def main(): 52 | word = input("请输入待翻译字符串: ") 53 | token = get_token() 54 | encrypted_word = get_encrypted_word(word) 55 | result = get_translation_result(encrypted_word, token) 56 | print("翻译结果为: ", result) 57 | 58 | 59 | if __name__ == "__main__": 60 | main() 61 | 62 | -------------------------------------------------------------------------------- /JSReverse/dict_cnki_net/cnki_encrypt.js: -------------------------------------------------------------------------------- 1 | // 引用 crypto-js 加密模块 2 | var CryptoJS = require('crypto-js') 3 | 4 | function s(t) { 5 | var n = "4e87183cfd3a45fe" 6 | var e = { 7 | mode: CryptoJS.mode.ECB, 8 | padding: CryptoJS.pad.Pkcs7 9 | } 10 | , i = CryptoJS.enc.Utf8.parse(n) 11 | , s = CryptoJS.AES.encrypt(t, i, e) 12 | , r = s.toString().replace(/\//g, "_"); 13 | return r = r.replace(/\+/g, "-"), 14 | r 15 | } 16 | 17 | // 测试样例 18 | // console.log(s("测试")) 19 | -------------------------------------------------------------------------------- /JSReverse/epay_163_com/epay.js: -------------------------------------------------------------------------------- 1 | // 引用 crypto-js 加密模块 2 | 3 | var CryptoJS = require('crypto-js') 4 | 5 | function getEncryptedPassword(password, peEnSeed) { 6 | var pwd = CryptoJS.enc.Utf8.parse(CryptoJS.MD5(password)); 7 | var key = CryptoJS.enc.Utf8.parse(peEnSeed); 8 | var iv = CryptoJS.enc.Utf8.parse("0123456789012345"); 9 | var encrypted = CryptoJS.AES.encrypt(pwd, key, { 10 | iv: iv, 11 | mode: CryptoJS.mode.CBC, 12 | padding: CryptoJS.pad.Pkcs7 13 | }); 14 | 15 | return pwd ? key ? encodeURIComponent(encrypted.toString()) : pwd : "" 16 | } 17 | 18 | // 测试样例 19 | // var password = "123456" 20 | // var peEnSeed = "2F63CCD861E4397F1C2181006904BAB2" 21 | // console.log(getEncryptedPassword(password, peEnSeed)) 22 | -------------------------------------------------------------------------------- /JSReverse/etherrock_ne/airdrop_submit.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-11-24 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: airdrop_submit.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | def get_content_and_key(address): 17 | with open("get_content_and_key.js", encoding="utf-8") as f: 18 | ether_rock_js = f.read() 19 | content_and_key_dict = execjs.compile(ether_rock_js).call('getContentAndKey', address) 20 | return content_and_key_dict 21 | 22 | 23 | def airdrop_submit(content_and_key_dict): 24 | submit_url = "https://etherrock.net/airdrop-submit" 25 | headers = { 26 | "Accept": "text/html, */*; q=0.01", 27 | "Accept-Language": "zh,zh-CN;q=0.9,en-US;q=0.8,en;q=0.7", 28 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36", 29 | "X-Requested-With": "XMLHttpRequest", 30 | "Host": "etherrock.net", 31 | "Origin": "https://etherrock.net", 32 | } 33 | data = { 34 | "content": content_and_key_dict["content"], 35 | "key": content_and_key_dict["key"] 36 | } 37 | response = requests.post(url=submit_url, data=data, headers=headers) 38 | print(response.text) 39 | 40 | 41 | def main(): 42 | address = input("请输入ETH钱包地址领取空投: ") 43 | content_and_key_dict = get_content_and_key(address) 44 | airdrop_submit(content_and_key_dict) 45 | 46 | 47 | if __name__ == '__main__': 48 | main() 49 | 50 | -------------------------------------------------------------------------------- /JSReverse/etherrock_ne/get_content_and_key.js: -------------------------------------------------------------------------------- 1 | function randomString(N) { 2 | if (!parseInt(N, 10)) N = 6; 3 | var rs = Math.floor(Math.pow(36, N) * Math.random()).toString(36); 4 | return (Math.pow(10, N) + rs).substr(-N); 5 | } 6 | 7 | var h = require("node-cryptojs-aes").CryptoJS 8 | , p = { 9 | stringify: function (b) { 10 | var e = h.enc.Hex.parse(b.salt.toString()).toString(h.enc.Latin1); 11 | b = b.ciphertext.toString(h.enc.Latin1); 12 | return h.enc.Latin1.parse("Salted__" + e + b).toString(h.enc.Base64) 13 | }, 14 | parse: function (b) { 15 | b = h.enc.Base64.parse(b).toString(h.enc.Latin1); 16 | if ("Salted__" !== b.substr(0, 8)) 17 | throw Error("Error parsing salt"); 18 | var e = b.substr(8, 8); 19 | b = b.substr(16); 20 | return h.lib.CipherParams.create({ 21 | ciphertext: h.enc.Latin1.parse(b), 22 | salt: h.enc.Latin1.parse(e) 23 | }) 24 | } 25 | }; 26 | 27 | var e = randomString(36); 28 | 29 | function getContent(address) { 30 | var b = JSON.stringify({ 31 | "address": address, 32 | "ref": "", 33 | "uuid": "", 34 | "tz": "Asia/Shanghai", 35 | "tz_offset": 8, 36 | "screen": "1920x1080x24", 37 | "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36", 38 | "cpu": 8, 39 | "lang": "zh" 40 | }) 41 | return h.AES.encrypt(b, e, { 42 | format: p 43 | }).toString() 44 | } 45 | 46 | function getKey() { 47 | JSEncrypt = require("jsencrypt") 48 | var crypt = new JSEncrypt(); 49 | var pub = [ 50 | '-----BEGIN PUBLIC KEY-----', 51 | 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVmYQhCYTnnkTPRMI5Ad3vfad9', 52 | 'lhjzOU92FZ3reUiN/vmqP/wC1DKKExYDsqa+w5xBP0AjGkfDWk3q4PlWu0UsBGZx', 53 | '62Gvt0ds75u8FnmLv+ufMimF4962/9Lx7uyh9g1H3/ze5ZXscWYy3gtts9d2Ga0R', 54 | 'pl0X49Cz0JhYYicuGwIDAQAB', 55 | '-----END PUBLIC KEY-----', 56 | ]; 57 | crypt.setPublicKey(pub.join('\n')); 58 | key = crypt.encrypt(e); 59 | return key 60 | } 61 | 62 | function getContentAndKey(address) { 63 | result = { 64 | "key": getKey(), 65 | "content": getContent(address) 66 | } 67 | return result 68 | } 69 | 70 | 71 | // 测试样例 72 | // console.log(getContentAndKey("xxxxxxxxxxxxxxxx")) 73 | -------------------------------------------------------------------------------- /JSReverse/fanyi_baidu_com/baidu_encrypt.js: -------------------------------------------------------------------------------- 1 | var i = '320305.131321201' 2 | 3 | function n(r, o) { 4 | for (var t = 0; t < o.length - 2; t += 3) { 5 | var a = o.charAt(t + 2); 6 | a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a), a = "+" === o.charAt(t + 1) ? r >>> a : r << a, r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a 7 | } 8 | return r 9 | } 10 | 11 | function e(r) { 12 | var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g); 13 | if (null === o) { 14 | var t = r.length; 15 | t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10)) 16 | } else { 17 | for (var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++) "" !== e[C] && f.push.apply(f, a(e[C].split(""))), C !== h - 1 && f.push(o[C]); 18 | var g = f.length; 19 | g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(-10).join("")) 20 | } 21 | var u = void 0, l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107); 22 | u = null !== i ? i : (i = window[l] || "") || ""; 23 | for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) { 24 | var A = r.charCodeAt(v); 25 | 128 > A ? S[c++] = A : (2048 > A ? S[c++] = A >> 6 | 192 : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? (A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v)), S[c++] = A >> 18 | 240, S[c++] = A >> 12 & 63 | 128) : S[c++] = A >> 12 | 224, S[c++] = A >> 6 & 63 | 128), S[c++] = 63 & A | 128) 26 | } 27 | for (var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++) p += S[b], p = n(p, F); 28 | return p = n(p, D), p ^= s, 0 > p && (p = (2147483647 & p) + 2147483648), p %= 1e6, p.toString() + "." + (p ^ m) 29 | } 30 | 31 | // console.log(e('测试')) 32 | -------------------------------------------------------------------------------- /JSReverse/fanyi_baidu_com/baidufanyi.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: baidufanyi.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import re 13 | 14 | import execjs 15 | import requests 16 | 17 | 18 | index_url = 'https://fanyi.baidu.com/' 19 | lang_url = 'https://fanyi.baidu.com/langdetect' 20 | translate_api = 'https://fanyi.baidu.com/v2transapi' 21 | headers = { 22 | 'Accept': '*/*', 23 | 'Accept-Encoding': 'gzip, deflate, br', 24 | 'Accept-Language': 'zh,zh-CN;q=0.9,en-US;q=0.8,en;q=0.7', 25 | 'Connection': 'keep-alive', 26 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 27 | 'Cookie': 'BIDUPSID=3BE16D933E9C0182F2A6E93D7A9D1424; PSTM=1623723330; BAIDUID=8496908995397662040287D2CE1C4224:FG=1; __yjs_duid=1_779078c2c847bb3217554b8549ad49bd1623728424311; REALTIME_TRANS_SWITCH=1; HISTORY_SWITCH=1; FANYI_WORD_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; BDSFRCVID_BFESS=BkFOJeCT5G3_WP5eFqJ2T4D2p2KKN9OTTPjcTR5qJ04BtyCVNKsaEG0PtOgMNBDbJ2MRogKKLgOTHULF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF_BFESS=tJ4toCPMJI_3fP36q45HMt00qxby26PDajn9aJ5nQI5nhU7505oqDJ0Z0ROOWhRute3i2DTvQUbmjRO206oay6O3LlO83h5wW57KKl0MLPbcep68LxODy6DI0xnMBMnr52OnaU513fAKftnOM46JehL3346-35543bRTLnLy5KJYMDF4D5_ae5O3DGRf-b-XKD600PK8Kb7VbUF6qfnkbft7jtteyhbTJCID-UQKQPnc_pC4yURFef473b3B5h3NJ66ZoIbPbPTTSlroKPQpQT8r5-nMWx6G3IrZoq64ab3vOpRTXpO13fAzBN5thURB2DkO-4bCWJ5TMl5jDh3Mb6ksD-FtqjDjJRCOoI--f-3bfTrP-trf5DCShUFs3tnlB2Q-5M-a3KOrSUtGbfjay6D7j-8HbTjiW2_82MbmLncjSM_GKfC2jMD32tbpWfneKmTxoUJ2Bb3Y8loe-xCKXqDebPRiWPb9QgbP2pQ7tt5W8ncFbT7l5hKpbt-q0x-jLTnhVn0MBCK0HPonHjKbDTvL3f; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1624438637,1624603638,1624928461,1624953786; H_PS_PSSID=34131_34099_31253_34004_33607_34107_34135; delPer=0; PSINO=6; BAIDUID_BFESS=8496908995397662040287D2CE1C4224:FG=1; BDRCVFR[X_XKQks0S63]=mk3SLVN4HKm; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1624962661; __yjs_st=2_MzJhZTMxZGU5MjZjNGJiZTJiZjQwYjVkMWM5ZjYyMGFjZDlkMDJmNTU3OGU5ZTM4N2JjNjNkODAwYWJiY2M3NDA1NWEyODNkMzNkMDEzNThiZTU4NzNhMTQxYzIxOTQyMzg3MjhiMzA5ZjY2MDczZTBhZDdmZDg4YTFhNjVmZTMwZTYyZTRjNmRhMWNmYzg3NDFjODYzYTRlZTE2NzBmODAyMWI4MTI3NTZmNjg1MDk4OWIxZTYzNTc4NzhjY2E3NzU3ZGYyZmI1ODdjZTM5ZDNlOGU0ZGQ2NzE5OGU2NzUzM2ZhZTcxZmVjNjI4MDIyN2Y1N2NlMzZmMmRlY2U4Yl83XzQ5NzQ4ZWE4; ab_sr=1.0.1_MmUwODU0NGE4NjIwZmY4NjgxZmM1NGYxOTI5ZWQwOGU2NjU3ZjgwNzhkMTNjNDI5NWE0ODQwYzlkZDVjY2Q1YWEyZDQyZWI0ZjNkMWQ0NTEyMGFjYzdiNDdmNzYxYjNiMjkxZTI1M2I3Y2VhZGE3NDEzOTgyMjY1MjBlZGM4OGJiZGVjMzFkYTM3ODgyMTRkZjJhMGYzNGM0MGJmMGY1Yg==', 28 | 'Host': 'fanyi.baidu.com', 29 | 'Origin': 'https://fanyi.baidu.com', 30 | 'Referer': 'https://fanyi.baidu.com/', 31 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 32 | 'sec-ch-ua-mobile': '?0', 33 | 'Sec-Fetch-Dest': 'empty', 34 | 'Sec-Fetch-Mode': 'cors', 35 | 'Sec-Fetch-Site': 'same-origin', 36 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', 37 | 'X-Requested-With': 'XMLHttpRequest' 38 | } 39 | 40 | 41 | def get_token(): 42 | response = requests.get(url=index_url, headers=headers).text 43 | token = re.findall(r"token: '([0-9a-z]+)", response)[0] 44 | return token 45 | 46 | 47 | def get_sign(query): 48 | with open('baidu_encrypt.js', 'r', encoding='utf-8') as f: 49 | baidu_js = f.read() 50 | sign = execjs.compile(baidu_js).call('e', query) 51 | return sign 52 | 53 | 54 | def get_result(lang, query, sign, token): 55 | data = { 56 | 'from': lang, 57 | 'to': 'en', 58 | 'query': query, 59 | 'transtype': 'realtime', 60 | 'simple_means_flag': '3', 61 | 'sign': sign, 62 | 'token': token, 63 | } 64 | response = requests.post(url=translate_api, headers=headers, data=data) 65 | result = response.json()['trans_result']['data'][0]['dst'] 66 | return result 67 | 68 | 69 | def main(): 70 | query = input('请输入要翻译的文字:') 71 | response = requests.post(url=lang_url, headers=headers, data={'query': query}) 72 | lang = response.json()['lan'] 73 | token = get_token() 74 | sign = get_sign(query) 75 | result = get_result(lang, query, sign, token) 76 | print('翻译成英文的结果为:', result) 77 | 78 | 79 | if __name__ == '__main__': 80 | main() 81 | -------------------------------------------------------------------------------- /JSReverse/fanyi_youdao_com/youdao_encrypt.js: -------------------------------------------------------------------------------- 1 | // 引用 crypto-js 加密模块 2 | var CryptoJS = require('crypto-js') 3 | 4 | function getEncryptedParams(data, ua) { 5 | var bv = CryptoJS.MD5(ua).toString(), 6 | lts = "" + (new Date).getTime(), 7 | salt = lts + parseInt(10 * Math.random(), 10) 8 | var sign = CryptoJS.MD5('fanyideskweb' + data + salt + ']BjuETDhU)zqSxf-=B#7m').toString() 9 | return { bv: bv, lts: lts, salt: salt, sign: sign } 10 | } 11 | 12 | // var ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 13 | // var data = "测试" 14 | // console.log(getEncryptedParams(data, ua)); -------------------------------------------------------------------------------- /JSReverse/fanyi_youdao_com/youdaofanyi.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: youdaofanyi.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import time 13 | import random 14 | import hashlib 15 | 16 | import execjs 17 | import requests 18 | 19 | 20 | translate_url = 'https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule' 21 | user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 22 | 23 | 24 | def get_translation_result(parameters): 25 | headers = { 26 | 'User-Agent': user_agent, 27 | 'Host': 'fanyi.youdao.com', 28 | 'Origin': 'https://fanyi.youdao.com', 29 | 'Referer': 'https://fanyi.youdao.com/', 30 | 'X-Requested-With': 'XMLHttpRequest', 31 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 32 | 'Cookie': 'OUTFOX_SEARCH_USER_ID="-1848382357@10.169.0.84"; ___rl__test__cookies=1625907853887; OUTFOX_SEARCH_USER_ID_NCOO=132978720.55854891' 33 | } 34 | response = requests.post(url=translate_url, headers=headers, data=parameters) 35 | result = response.json()['translateResult'][0][0]['tgt'] 36 | return result 37 | 38 | 39 | def get_parameters_by_python(query, translate_from, translate_to): 40 | lts = str(int(time.time() * 1000)) # 以毫秒为单位的 13 位时间戳 41 | salt = lts + str(random.randint(0, 9)) # 13 位时间戳+随机数字,生成 salt 值 42 | sign = "fanyideskweb" + query + salt + "Y2FYu%TNSbMCxc3t2u^XT" # 拼接字符串进行 MD5 加密,生成 sign 值 43 | sign = hashlib.md5(sign.encode()).hexdigest() 44 | bv = hashlib.md5(user_agent.encode()).hexdigest() # 对 UA 进行 MD5 加密,生成 bv 值 45 | parameters = { 46 | 'i': query, 47 | 'from': translate_from, 48 | 'to': translate_to, 49 | 'smartresult': 'dict', 50 | 'client': 'fanyideskweb', 51 | 'salt': salt, 52 | 'sign': sign, 53 | 'lts': lts, 54 | 'bv': bv, 55 | 'doctype': 'json', 56 | 'version': '2.1', 57 | 'keyfrom': 'fanyi.web', 58 | 'action': 'FY_BY_REALTlME' 59 | } 60 | return parameters 61 | 62 | 63 | def get_parameters_by_javascript(query, translate_from, translate_to): 64 | with open('youdao_encrypt.js', 'r', encoding='utf-8') as f: 65 | youdao_js = f.read() 66 | params = execjs.compile(youdao_js).call('get_params', query, user_agent) # 通过 JavaScript 代码获取各个参数 67 | bv = hashlib.md5(user_agent.encode()).hexdigest() # 对 UA 进行 MD5 加密,生成 bv 值 68 | parameters = { 69 | 'i': query, 70 | 'from': translate_from, 71 | 'to': translate_to, 72 | 'smartresult': 'dict', 73 | 'client': 'fanyideskweb', 74 | 'salt': params['salt'], 75 | 'sign': params['sign'], 76 | 'lts': params['lts'], 77 | 'bv': bv, 78 | 'doctype': 'json', 79 | 'version': '2.1', 80 | 'keyfrom': 'fanyi.web', 81 | 'action': 'FY_BY_REALTlME' 82 | } 83 | return parameters 84 | 85 | 86 | def main(): 87 | query = input('请输入要翻译的文字:') 88 | # 原始语言,目标语言,默认自动处理 89 | translate_from = translate_to = 'AUTO' 90 | # 通过 Python 获取加密参数或者通过 JavaScript 获取参数,二选一 91 | param = get_parameters_by_python(query, translate_from, translate_to) 92 | # param = get_parameters_by_javascript(query, translate_from, translate_to) 93 | result = get_translation_result(param) 94 | print('翻译的结果为:', result) 95 | 96 | 97 | if __name__ == '__main__': 98 | main() 99 | -------------------------------------------------------------------------------- /JSReverse/fuwu_nhsa_gov_cn/nhsa.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-11-03 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: nhsa.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | regn_code_url = "https://fuwu.nhsa.gov.cn/ebus/fuwu/api/nthl/api/dic/queryAdmdvsTree" 17 | lv_and_type_url = "https://fuwu.nhsa.gov.cn/ebus/fuwu/api/nthl/api/fixed/queryDicByType" 18 | result_url = "https://fuwu.nhsa.gov.cn/ebus/fuwu/api/nthl/api/fixed/queryFixedHospital" 19 | UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36" 20 | 21 | with open('nhsa.js', 'r', encoding='utf-8') as f: 22 | nhsa_js = execjs.compile(f.read()) 23 | 24 | 25 | def get_headers(): 26 | """获取 header 参数,每次请求改变""" 27 | headers = nhsa_js.call("getHeaders") 28 | headers["User-Agent"] = UA 29 | headers["Content-Type"] = "application/json" 30 | headers["Host"] = "fuwu.nhsa.gov.cn" 31 | headers["Origin"] = "https://fuwu.nhsa.gov.cn" 32 | headers["Referer"] = "https://fuwu.nhsa.gov.cn/nationalHallSt/" 33 | # print(headers) 34 | return headers 35 | 36 | 37 | def get_regn_code(): 38 | """获取城市代码,返回结果无加密""" 39 | payload = {"data": {"transferFlag": ""}} 40 | response = requests.post(url=regn_code_url, json=payload, headers=get_headers()) 41 | print(response.text) 42 | 43 | 44 | def get_medins_lv_or_type_code(key): 45 | """获取医疗机构等级 (LV) or 类型 (TYPE) 代码""" 46 | if key == "LV": 47 | payload = {"type": "MEDINSLV"} 48 | elif key == "TYPE": 49 | payload = {"type": "MEDINS_TYPE"} 50 | else: 51 | print("输入有误!") 52 | return 53 | encrypted_payload = nhsa_js.call("getEncryptedData", payload) 54 | encrypted_data = requests.post(url=lv_and_type_url, json=encrypted_payload, headers=get_headers()).json() 55 | decrypted_data = nhsa_js.call("getDecryptedData", encrypted_data) 56 | print(decrypted_data) 57 | 58 | 59 | def get_result(): 60 | addr = input("请输入医疗机构详细地址(默认无): ") or "" 61 | medins_lv_code = input("请输入医疗机构等级代码(默认无): ") or "" 62 | medins_name = input("请输入医疗机构名称(默认无): ") or "" 63 | medins_type_code = input("请输入医疗机构类型代码(默认无): ") or "" 64 | regn_code = input("请输入医疗机构所在地代码(默认北京市): ") or "110000" 65 | page_num = input("请输入要爬取的页数(默认1): ") or 1 66 | 67 | for page in range(1, int(page_num)+1): 68 | payload = { 69 | "addr": addr, 70 | "medinsLvCode": medins_lv_code, 71 | "medinsName": medins_name, 72 | "medinsTypeCode": medins_type_code, 73 | "pageNum": page, 74 | "pageSize": 10, 75 | "regnCode": regn_code, 76 | "sprtEcFlag": "" 77 | } 78 | page += 1 79 | encrypted_payload = nhsa_js.call("getEncryptedData", payload) 80 | encrypted_data = requests.post(url=result_url, json=encrypted_payload, headers=get_headers()).json() 81 | decrypted_data = nhsa_js.call("getDecryptedData", encrypted_data) 82 | print(decrypted_data) 83 | 84 | 85 | def main(): 86 | # 获取城市代码 87 | # get_regn_code() 88 | # 获取医疗机构等级代码 89 | # get_medins_lv_or_type_code("LV") 90 | # 获取医疗机构类型代码 91 | # get_medins_lv_or_type_code("TYPE") 92 | # 获取搜索结果 93 | get_result() 94 | 95 | 96 | if __name__ == "__main__": 97 | main() 98 | -------------------------------------------------------------------------------- /JSReverse/i_360_cn/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/JSReverse/i_360_cn/code.png -------------------------------------------------------------------------------- /JSReverse/jzsc_mohurd_gov_cn/jzsc_mohurd.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: jzsc_mohurd.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import json 13 | 14 | import execjs 15 | import requests 16 | 17 | 18 | data_url = 'http://jzsc.mohurd.gov.cn/api/webApi/dataservice/query/comp/list?pg=%s&pgsz=15&total=450' 19 | 20 | 21 | def get_encrypted_data(page): 22 | headers = { 23 | 'Host': 'jzsc.mohurd.gov.cn', 24 | 'Referer': 'http://jzsc.mohurd.gov.cn/data/company', 25 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 26 | } 27 | encrypted_data = requests.get(url=data_url % page, headers=headers).text 28 | return encrypted_data 29 | 30 | 31 | def get_decrypted_data(encrypted_data): 32 | with open('jzsc_mohurd_decrypt.js', 'r', encoding='utf-8') as f: 33 | jzsc_mohurd_js = f.read() 34 | decrypted_data = execjs.compile(jzsc_mohurd_js).call('getDecryptedData', encrypted_data) 35 | return json.loads(decrypted_data) 36 | 37 | 38 | def main(): 39 | # 30页数据 40 | for page in range(30): 41 | encrypted_data = get_encrypted_data(page) 42 | decrypted_data = get_decrypted_data(encrypted_data) 43 | print(decrypted_data) 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /JSReverse/learn_open_com_cn/get_black_box.js: -------------------------------------------------------------------------------- 1 | // 获取 black_box 参数 2 | 3 | 4 | function oQ0OQ(Q0o0, o0OQ) { 5 | return Q0o0 < o0OQ; 6 | } 7 | 8 | function O000O(Q0o0, o0OQ) { 9 | return Q0o0 >> o0OQ; 10 | } 11 | 12 | function Qo0oo(Q0o0, o0OQ) { 13 | return Q0o0 | o0OQ; 14 | } 15 | 16 | function OOO0Q(Q0o0, o0OQ) { 17 | return Q0o0 << o0OQ; 18 | } 19 | 20 | function OooQo(Q0o0, o0OQ) { 21 | return Q0o0 & o0OQ; 22 | } 23 | 24 | function Oo0OO(Q0o0, o0OQ) { 25 | return Q0o0 + o0OQ; 26 | } 27 | 28 | var oQoo0 = {}; 29 | oQoo0["_keyStr"] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", 30 | oQoo0["encode"] = function QQQ0(Q0o0) { 31 | var o0OQ = 62; 32 | while (o0OQ) { 33 | switch (o0OQ) { 34 | case 116 + 13 - 65: { 35 | var Q000; 36 | var Q00O; 37 | var OQO0 = 0; 38 | o0OQ = 65; 39 | break; 40 | } 41 | case 118 + 8 - 63: { 42 | var QQoO; 43 | var oQOQ; 44 | var ooQQ; 45 | o0OQ = 64; 46 | break; 47 | } 48 | case 94 + 8 - 40: { 49 | var ooO0 = ""; 50 | var QQOQ; 51 | var QOo0; 52 | o0OQ = 63; 53 | break; 54 | } 55 | case 122 + 6 - 63: { 56 | Q0o0 = oQoo0["_utf8_encode"](Q0o0); 57 | var Q0oO = 9; 58 | while (Q0oO) { 59 | switch (Q0oO) { 60 | case 59 + 11 - 60: { 61 | QQOQ = Q0o0["charCodeAt"](OQO0++), 62 | QOo0 = Q0o0["charCodeAt"](OQO0++), 63 | QQoO = Q0o0["charCodeAt"](OQO0++), 64 | oQOQ = O000O(QQOQ, 2), 65 | ooQQ = Qo0oo(OOO0Q(OooQo(QQOQ, 3), 4), O000O(QOo0, 4)), 66 | Q000 = Qo0oo(OOO0Q(OooQo(QOo0, 15), 2), O000O(QQoO, 6)), 67 | Q00O = OooQo(QQoO, 63); 68 | if (isNaN(QOo0)) { 69 | Q000 = Q00O = 64; 70 | } else if (isNaN(QQoO)) { 71 | Q00O = 64; 72 | } 73 | Q0oO = 11; 74 | break; 75 | } 76 | case 50 + 15 - 56: { 77 | Q0oO = oQ0OQ(OQO0, Q0o0["length"]) ? 10 : 0; 78 | break; 79 | } 80 | case 95 + 5 - 89: { 81 | ooO0 = Oo0OO(Oo0OO(Oo0OO(Oo0OO(ooO0, this["_keyStr"]["charAt"](oQOQ)), this["_keyStr"]["charAt"](ooQQ)), this["_keyStr"]["charAt"](Q000)), this["_keyStr"]["charAt"](Q00O)); 82 | Q0oO = 9; 83 | break; 84 | } 85 | } 86 | } 87 | return ooO0; 88 | } 89 | } 90 | } 91 | }; 92 | oQoo0["_utf8_encode"] = function oOQ0(Q0o0) { 93 | Q0o0 = Q0o0["replace"](/\r\n/g, ""); 94 | var o0OQ = ""; 95 | for (var Q000 = 0; oQ0OQ(Q000, Q0o0["length"]); Q000++) { 96 | var Q00O = Q0o0["charCodeAt"](Q000); 97 | if (oQ0OQ(Q00O, 128)) { 98 | o0OQ += String["fromCharCode"](Q00O); 99 | } else if (Q0OQO(Q00O, 127) && oQ0OQ(Q00O, 2048)) { 100 | o0OQ += String["fromCharCode"](Qo0oo(O000O(Q00O, 6), 192)), 101 | o0OQ += String["fromCharCode"](Qo0oo(OooQo(Q00O, 63), 128)); 102 | } else { 103 | o0OQ += String["fromCharCode"](Qo0oo(O000O(Q00O, 12), 224)), 104 | o0OQ += String["fromCharCode"](Qo0oo(OooQo(O000O(Q00O, 6), 63), 128)), 105 | o0OQ += String["fromCharCode"](Qo0oo(OooQo(Q00O, 63), 128)); 106 | } 107 | } 108 | return o0OQ; 109 | } 110 | 111 | function OOoO0() { 112 | var tokens = "e0ia+fB5zvGuTjFDgcKahQwg2UEH8b0k7EK/Ukt4KwzyCbpm11jjy8Au64MC6s7HvLRacUxd7ka4AdDidJmYAA=="; 113 | var version = "+X+3JWoUVBc12xtmgMpwzjAone3cp6/4QuFj7oWKNk+C4tqy4un/e29cODlhRmDy"; 114 | var Oo0O0 = {}; 115 | Oo0O0["blackBox"] = {}; 116 | Oo0O0["blackBox"]["v"] = version; 117 | Oo0O0["blackBox"]["os"] = "web"; 118 | Oo0O0["blackBox"]["it"] = parseInt(Math.random() * 100000); 119 | Oo0O0["blackBox"]["t"] = tokens; 120 | return oQoo0["encode"](JSON.stringify(Oo0O0["blackBox"])); 121 | } 122 | 123 | // 测试样例 124 | // console.log(OOoO0()) 125 | -------------------------------------------------------------------------------- /JSReverse/learn_open_com_cn/open_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-11-10 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: open_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import time 13 | import execjs 14 | import requests 15 | 16 | 17 | login_url = "https://learn.open.com.cn/Account/UnitLogin" 18 | 19 | 20 | def get_black_box(): 21 | with open('get_black_box.js', 'r', encoding='utf-8') as f: 22 | exec_js = f.read() 23 | black_box = execjs.compile(exec_js).call('OOoO0') 24 | return black_box 25 | 26 | 27 | def login(black_box, username, password): 28 | params = {"bust": str(int(time.time() * 1000))} 29 | data = { 30 | "loginName": username, 31 | "passWord": password, 32 | "validateNum": "", 33 | "black_box": black_box 34 | } 35 | headers = { 36 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36" 37 | } 38 | response = requests.post(url=login_url, params=params, data=data, headers=headers) 39 | print(response.json()) 40 | 41 | 42 | def main(): 43 | username = input("请输入登录账号: ") 44 | password = input("请输入登录密码: ") 45 | black_box = get_black_box() 46 | login(black_box, username, password) 47 | 48 | 49 | if __name__ == '__main__': 50 | main() 51 | 52 | -------------------------------------------------------------------------------- /JSReverse/login_189_cn/189_encrypt.js: -------------------------------------------------------------------------------- 1 | // 引用 crypto-js 加密模块 2 | CryptoJS = require("crypto-js") 3 | 4 | function aesEncrypt(e) { 5 | var a = CryptoJS.MD5("login.189.cn"); 6 | var c = CryptoJS.enc.Utf8.parse(a); 7 | var b = CryptoJS.enc.Utf8.parse("1234567812345678"); 8 | var d = CryptoJS.AES.encrypt(e, c, { 9 | iv: b 10 | }); 11 | return d + "" 12 | }; 13 | 14 | function aesDecrypt(e) { 15 | var b = CryptoJS.MD5("login.189.cn"); 16 | var d = CryptoJS.enc.Utf8.parse(b); 17 | var c = CryptoJS.enc.Utf8.parse("1234567812345678"); 18 | var a = CryptoJS.AES.decrypt(e, d, { 19 | iv: c 20 | }).toString(CryptoJS.enc.Utf8); 21 | return a 22 | }; 23 | 24 | function valAesEncryptSet(d) { 25 | // var d = this.val(); 26 | var a, c; 27 | try { 28 | a = aesDecrypt(d); 29 | if (a != "") { 30 | c = aesEncrypt(a); 31 | if (c != d) { 32 | a = "" 33 | } 34 | } 35 | } catch (b) { 36 | a = "" 37 | } 38 | if (a == "") { 39 | c = aesEncrypt(d) 40 | } 41 | // this.val(c); 42 | // return this.val() 43 | return c 44 | }; 45 | 46 | function checkIsCellphone(account) { 47 | //alert("checkIsCellphone"); 48 | var checkResult = false; 49 | var regExp = /^1[3456789]\d{9}$/; //baidu js 50 | if (regExp.test(account)) { 51 | checkResult = true; 52 | } 53 | return checkResult; 54 | } 55 | 56 | function checkIsCellphoneForCT(account) { 57 | //alert("checkIsCellphoneForCT"); 58 | var checkResult = true;//2014-11-01 59 | var regExp = /^(1[35]3|18[901]|177)\d{8}|1700\d{3}$/; 60 | if (regExp.test(account)) { 61 | checkResult = true; 62 | } 63 | return checkResult; 64 | } 65 | 66 | function checkIsTelephone(account) { 67 | //alert("checkIsTelephone"); 68 | var checkResult = false; 69 | var regExp = /(^\d{7,8}$)|(^0\d{10,12}$)/; 70 | if (regExp.test(account)) { 71 | checkResult = true; 72 | } 73 | return checkResult; 74 | } 75 | 76 | function checkIsMail(account) { 77 | //alert("checkIsMail"); 78 | var checkResult = false; 79 | var regExp = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; //baidu js 80 | if (regExp.test(account)) { 81 | checkResult = true; 82 | } 83 | return checkResult; 84 | } 85 | 86 | // 测试样例 87 | // console.log(valAesEncryptSet("123321")) 88 | -------------------------------------------------------------------------------- /JSReverse/login_189_cn/189_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-13 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: 189_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import json 13 | 14 | import execjs 15 | import requests 16 | from PIL import Image 17 | from lxml import etree 18 | 19 | 20 | login_url = 'https://login.189.cn/web/login' 21 | captcha_image_url = 'https://login.189.cn/web/captcha' 22 | ajax_url = 'https://login.189.cn/web/login/ajax' 23 | headers = { 24 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 25 | } 26 | session = requests.session() 27 | 28 | with open('189_encrypt.js', 'r', encoding='utf-8') as f: 29 | exec_js = f.read() 30 | 31 | 32 | def check_login_type(username): 33 | # 正常手机号登录,例如 13366666666 34 | if execjs.compile(exec_js).call('checkIsCellphone', username): 35 | return 201 36 | 37 | # 这个检测似乎没有用,但是在原 JS 中是存在的 38 | # elif execjs.compile(exec_js).call('checkIsCellphoneForCT', username): 39 | # u_type = ??? 40 | 41 | # 固话、宽带登录,例如 8637222 42 | elif execjs.compile(exec_js).call('checkIsTelephone', username): 43 | return judge_broadband_or_landline() 44 | 45 | # 邮件登录,例如 admin@itrhx.com 46 | elif execjs.compile(exec_js).call('checkIsMail', username): 47 | return 1 48 | 49 | # 其他情况默认是宽带,例如 1331700234、abcde 50 | else: 51 | return 203 52 | 53 | 54 | def judge_broadband_or_landline(): 55 | net_type = input('固话请输入1,宽带请输入2:') 56 | if net_type == '1': 57 | return 202 58 | elif net_type == '2': 59 | return 203 60 | else: 61 | print('输入有误,请重新输入!') 62 | judge_broadband_or_landline() 63 | 64 | 65 | def get_city_info(u_type, username): 66 | # 如果是宽带或者固话,手动选择城市,如武汉、重庆、阿坝州、恩施 67 | if u_type == 202 or u_type == 203: 68 | city = input('请输入城市名(中文):') 69 | data = {'m': 'querycity', 'key': city} 70 | response = session.post(url=ajax_url, data=data, headers=headers).text 71 | if response == '[]': 72 | raise Exception('对不起,找不到该城市!') 73 | else: 74 | city_info = json.loads(response.replace('[', '').replace(']', '')) 75 | # print(city_info) 76 | return city_info 77 | 78 | # 如果是手机号,则查询手机号归属地信息 79 | elif u_type == 201: 80 | data = {'m': 'checkphone', 'phone': username} 81 | response = session.post(url=ajax_url, data=data, headers=headers).text 82 | if response: 83 | city_info = json.loads(response) 84 | else: 85 | raise Exception('手机号归属地信息查询失败!') 86 | # print(city_info) 87 | return city_info 88 | 89 | # 其他情况不需要归属地信息,直接置空 90 | else: 91 | city_info = { 92 | 'phonesen': '', 'provinceId': '', 'provinceName': '', 93 | 'cityNo': '', 'cityName': '', 'areaCode': '', 94 | 'netId': None, 'cardType': None, 'remark': None 95 | } 96 | return city_info 97 | 98 | 99 | def get_encrypted_password(password): 100 | encrypted_password = execjs.compile(exec_js).call('valAesEncryptSet', password) 101 | return encrypted_password 102 | 103 | 104 | def get_captcha_code(): 105 | params = { 106 | 'undefined': '', 107 | 'source': 'login', 108 | 'width': '100', 109 | 'height': '37', 110 | '0.90480233478278': '' 111 | } 112 | response = session.get(url=captcha_image_url, params=params, headers=headers) 113 | with open('code.png', 'wb') as f: 114 | f.write(response.content) 115 | image = Image.open('code.png') 116 | image.show() 117 | code = input('请输入图片验证码: ') 118 | return code 119 | 120 | 121 | def login(username, encrypted_password, code, u_type, city_info): 122 | params = { 123 | 'Account': username, 124 | 'UType': u_type, 125 | 'ProvinceID': city_info['provinceId'], 126 | 'AreaCode': city_info['areaCode'], 127 | 'CityNo': city_info['cityNo'], 128 | 'Captcha': code, 129 | 'RandomFlag': '0', 130 | 'Password': encrypted_password 131 | } 132 | response = session.post(url=login_url, params=params, headers=headers) 133 | # print(response.text) 134 | """ 135 | 若登录失败,可在网页里找到失败的原因 136 | 登录成功会返回什么不知道,因为我没有电信手机来做实验 137 | """ 138 | try: 139 | tree = etree.HTML(response.text) 140 | errmsg = tree.xpath("//form[@id='loginForm']/@data-errmsg")[0] 141 | print('登录失败!', errmsg) 142 | except Exception as error: 143 | # print(error) 144 | pass 145 | 146 | 147 | def main(): 148 | username = input('请输入登录账号: ') 149 | password = input('请输入登录密码: ') 150 | 151 | # 根据登录账号判断登录类型,手机、邮箱、宽带、固话 152 | u_type = check_login_type(username) 153 | 154 | # 获取账号归属地信息 155 | city_info = get_city_info(u_type, username) 156 | 157 | # 获取加密后的密码 158 | encrypted_password = get_encrypted_password(password) 159 | 160 | # 获取验证码 161 | code = get_captcha_code() 162 | 163 | # 登录 164 | login(username, encrypted_password, code, u_type, city_info) 165 | 166 | 167 | if __name__ == '__main__': 168 | main() 169 | -------------------------------------------------------------------------------- /JSReverse/login_189_cn/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/JSReverse/login_189_cn/code.png -------------------------------------------------------------------------------- /JSReverse/login_flyme_cn/flyme_encrypt.js: -------------------------------------------------------------------------------- 1 | function excutePP(r, e) { 2 | for (var n = "", t = 0; t < r.length; t++) { 3 | var o = e ^ r.charCodeAt(t); 4 | n += String.fromCharCode(o) 5 | } 6 | return encodeURIComponent(n) 7 | } 8 | 9 | function generateMix(r) { 10 | return Math.ceil(1e3 * Math.random()) 11 | } 12 | 13 | function getEncryptedPassword(password) { 14 | var kk = generateMix(); 15 | return excutePP(password, kk); 16 | } 17 | 18 | // 测试样例 19 | // console.log(getEncryptedPassword("12345678")) 20 | -------------------------------------------------------------------------------- /JSReverse/login_flyme_cn/flyme_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-27 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: flyme_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | login_url = 'https://login.flyme.cn/sso/unionlogin' 17 | 18 | 19 | def get_encrypted_password(password): 20 | with open('flyme_encrypt.js', 'r', encoding='utf-8') as f: 21 | exec_js = f.read() 22 | encrypted_password = execjs.compile(exec_js).call('getEncryptedPassword', password) 23 | return encrypted_password 24 | 25 | 26 | def login(username, encrypted_password): 27 | headers = { 28 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 29 | } 30 | params = { 31 | 'cycode': '+86', 32 | 'account': '0086: %s' % username, 33 | 'password': encrypted_password, 34 | 'abnormal': '', 35 | 'kapkey': '', 36 | 'appuri': '', 37 | 'useruri': 'http://store.meizu.com/member/login.htm?useruri=http://www.meizu.com', 38 | 'service': 'store', 39 | 'sid': 'unionlogin', 40 | 'geetest_challenge': '', 41 | 'geetest_validate': '', 42 | 'geetest_seccode': '', 43 | 'unCommonlandedCode': '', 44 | } 45 | response = requests.post(url=login_url, params=params, headers=headers) 46 | print(response.json()) 47 | 48 | 49 | def main(): 50 | username = input('请输入登录账号: ') 51 | password = input('请输入登录密码: ') 52 | encrypted_password = get_encrypted_password(password) 53 | login(username, encrypted_password) 54 | 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /JSReverse/m_wcbchina_com/wcbchina_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-10-15 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: wcbchina_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import time 13 | import random 14 | import hashlib 15 | 16 | import execjs 17 | import requests 18 | 19 | 20 | login_url = 'https://m.wcbchina.com/api/login/login' 21 | 22 | 23 | def get_enpwd_and_sign_by_javascript(password): 24 | with open('wcbchina_encrypt.js', 'r', encoding='utf-8') as f: 25 | encrypt_js = execjs.compile(f.read()) 26 | encrypted_password = encrypt_js.call('getEncryptedPassword', password) 27 | sign = encrypt_js.call('getSign') 28 | return encrypted_password, sign 29 | 30 | 31 | def get_enpwd_and_sign_by_python(password): 32 | timestamp = str(int(time.time() * 1000)) 33 | encrypted_password = hashlib.md5(password.encode('utf-8')).hexdigest().upper() 34 | sign = hashlib.md5(timestamp.encode('utf-8')).hexdigest().upper() 35 | return encrypted_password, sign 36 | 37 | 38 | def get_rnd(): 39 | rnd = 'rnd' + str(random.uniform(0, 1)) 40 | return rnd 41 | 42 | 43 | def login(username, encrypted_password, sign, rnd): 44 | headers = { 45 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 46 | } 47 | json = { 48 | "auth": { 49 | "timestamp": str(int(time.time() * 1000)), 50 | "sign": sign 51 | }, 52 | "username": username, 53 | "password": encrypted_password 54 | } 55 | response = requests.post(url=login_url, params=rnd, json=json, headers=headers) 56 | print(response.json()) 57 | 58 | 59 | def main(): 60 | username = input('请输入登录账号: ') 61 | password = input('请输入登录密码: ') 62 | # 通过 JavaScript 代码获取加密后的密码和 sign 63 | encrypted_password, sign = get_enpwd_and_sign_by_javascript(password) 64 | # 通过 Python 代码获取加密后的密码和 sign 65 | # encrypted_password, sign = get_enpwd_and_sign_by_python(password) 66 | rnd = get_rnd() 67 | login(username, encrypted_password, sign, rnd) 68 | 69 | 70 | if __name__ == '__main__': 71 | main() 72 | -------------------------------------------------------------------------------- /JSReverse/max_pedata_cn/main.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-12-31 4 | # @Author : ITBOB 5 | # @Blog : www.itbob.cn 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: main.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | news_est_url = "https://max.pedata.cn/api/q4x/newsflash/list" 16 | login_token = "1796a48fa1968edd5c5d10d42c7b18139a33fcb392b9904a6c08079fc3a3068e" 17 | headers = { 18 | "Accept": "application/json, text/plain, */*", 19 | "Content-Type": "application/json", 20 | "Host": "max.pedata.cn", 21 | "HTTP-X-TOKEN": login_token, 22 | "Origin": "https://max.pedata.cn", 23 | "Referer": "https://max.pedata.cn/client/news/newsflash", 24 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" 25 | } 26 | 27 | 28 | def get_decrypted_data(encrypted_data, exor): 29 | with open('pedata_decrypt.js', 'r', encoding='utf-8') as f: 30 | pedata_js = f.read() 31 | decrypted_data = execjs.compile(pedata_js).call('getDecryptedData', encrypted_data, exor, login_token) 32 | return decrypted_data 33 | 34 | 35 | def get_encrypted_data(): 36 | data = { 37 | "type": "", 38 | "module": "LP", 39 | "page": 40 | { 41 | "currentPage": 1, 42 | "pageSize": 10 43 | } 44 | } 45 | response = requests.post(url=news_est_url, headers=headers, json=data).json() 46 | encrypted_data, exor = response["data"], response["exor"] 47 | return encrypted_data, exor 48 | 49 | 50 | def main(): 51 | encrypted_data, exor = get_encrypted_data() 52 | decrypted_data = get_decrypted_data(encrypted_data, exor) 53 | print(decrypted_data) 54 | 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /JSReverse/oauth_d_cn/d_cn_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: d_cn_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | def get_encrypted_password(password): 17 | with open('d_cn_encrypt.js', 'r', encoding='utf-8') as f: 18 | weibo_js = f.read() 19 | encrypted_password = execjs.compile(weibo_js).call('getEncryptedPassword', password) 20 | return encrypted_password 21 | 22 | 23 | def login(encrypted_password, username): 24 | login_url = 'https://oauth.d.cn/auth/login' 25 | headers = { 26 | 'Host': 'oauth.d.cn', 27 | 'Referer': 'https://oauth.d.cn/auth/goLogin.html', 28 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 29 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 30 | } 31 | params = { 32 | 'display': 'web', 33 | 'name': username, 34 | 'pwd': encrypted_password, 35 | 'to': 'https%3A%2F%2Fwww.d.cn%2F' 36 | } 37 | response = requests.get(url=login_url, params=params, headers=headers).json() 38 | print(response) 39 | 40 | 41 | def main(): 42 | username = input('请输入登录账号: ') 43 | password = input('请输入登录密码: ') 44 | encrypted_password = get_encrypted_password(password) 45 | login(encrypted_password, username) 46 | 47 | 48 | if __name__ == '__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /JSReverse/passport_fang_com/fang_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: fang_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import re 13 | 14 | import execjs 15 | import requests 16 | 17 | 18 | index_url = 'https://passport.fang.com/' 19 | login_url = 'https://passport.fang.com/login.api' 20 | user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36' 21 | session = requests.session() 22 | 23 | 24 | def get_key_to_encode(): 25 | headers = {'User-Agent': user_agent} 26 | response = session.get(url=index_url, headers=headers) 27 | key_to_encode = re.findall(r'RSAKeyPair\((.*)\);', response.text)[0].replace('"', '').split(', ') 28 | return key_to_encode 29 | 30 | 31 | def get_encrypted_password(key_to_encode, pwd): 32 | n, i, t = key_to_encode[0], key_to_encode[1], key_to_encode[2] 33 | with open('fang_encrypt.js', 'r', encoding='utf-8') as f: 34 | fang_js = f.read() 35 | encrypted_pwd = execjs.compile(fang_js).call('getEncryptedPassword', pwd, n, i, t) 36 | return encrypted_pwd 37 | 38 | 39 | def login(encrypted_password, uid): 40 | headers = { 41 | 'User-Agent': user_agent, 42 | 'X-Requested-With': 'XMLHttpRequest', 43 | 'Host': 'passport.fang.com', 44 | 'Origin': 'https://passport.fang.com', 45 | 'Referer': 'https://passport.fang.com/?backurl=http%3a%2f%2fmy.fang.com%2f', 46 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 47 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' 48 | } 49 | data = { 50 | 'uid': uid, 51 | 'pwd': encrypted_password, 52 | 'Service': 'soufun-passport-web', 53 | 'AutoLogin': 1 54 | } 55 | response = session.post(url=login_url, data=data, headers=headers) 56 | print(response.json()) 57 | 58 | 59 | def main(): 60 | # 16521689404 61 | uid = input('请输入登录账号:') 62 | pwd = input('请输入登录密码:') 63 | rsa_key = get_key_to_encode() 64 | encrypted_pwd = get_encrypted_password(rsa_key, pwd) 65 | login(encrypted_pwd, uid) 66 | 67 | 68 | if __name__ == '__main__': 69 | main() 70 | -------------------------------------------------------------------------------- /JSReverse/passport_hqew_com/hqew_encrypt.js: -------------------------------------------------------------------------------- 1 | var CryptoJS = require('crypto-js') 2 | 3 | function SHA1Encrypt(word) { 4 | return CryptoJS.SHA1(word).toString(CryptoJS.enc.Hex); 5 | } 6 | 7 | function base64encode2(e) { 8 | var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 9 | var a, c, r, o, t, n; 10 | for (r = e.length, 11 | c = 0, 12 | a = ""; c < r; ) { 13 | if (o = 255 & e.charCodeAt(c++), 14 | c == r) { 15 | a += base64EncodeChars.charAt(o >> 2), 16 | a += base64EncodeChars.charAt((3 & o) << 4), 17 | a += "=="; 18 | break 19 | } 20 | if (t = e.charCodeAt(c++), 21 | c == r) { 22 | a += base64EncodeChars.charAt(o >> 2), 23 | a += base64EncodeChars.charAt((3 & o) << 4 | (240 & t) >> 4), 24 | a += base64EncodeChars.charAt((15 & t) << 2), 25 | a += "="; 26 | break 27 | } 28 | n = e.charCodeAt(c++), 29 | a += base64EncodeChars.charAt(o >> 2), 30 | a += base64EncodeChars.charAt((3 & o) << 4 | (240 & t) >> 4), 31 | a += base64EncodeChars.charAt((15 & t) << 2 | (192 & n) >> 6), 32 | a += base64EncodeChars.charAt(63 & n) 33 | } 34 | return a 35 | } 36 | 37 | // 测试样例 38 | // console.log(base64encode2("123123")) 39 | // console.log(base64encode2("1231234")) 40 | // console.log(SHA1Encrypt('719198916656926dc80e144287853608hqew')) 41 | -------------------------------------------------------------------------------- /JSReverse/passport_hqew_com/hqew_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: hqew_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import time 13 | import base64 14 | import hashlib 15 | 16 | import execjs 17 | import requests 18 | from lxml import etree 19 | 20 | 21 | index_url = 'https://passport.hqew.com/login' 22 | login_url = 'https://passport.hqew.com/Login/DoLogin' 23 | vistor_url = 'https://passport.hqew.com/hqewvistor?r===L2xvZ2lu&callback=HqewVistorCallback&_=%s' 24 | 25 | session = requests.session() 26 | headers = { 27 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 28 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 29 | } 30 | 31 | with open('hqew_encrypt.js', 'r', encoding='utf-8') as f: 32 | hqew_js = f.read() 33 | 34 | 35 | def get_encrypted_username_password(username, password): 36 | """ 用户名密码通过 base64 加密,可以使用 Python 实现,也可以调用 JS 实现""" 37 | # 调用 JS 38 | encrypted_username = execjs.compile(hqew_js).call('base64encode2', username) 39 | encrypted_password = execjs.compile(hqew_js).call('base64encode2', password) 40 | 41 | # 使用 Python 42 | # encrypted_username = base64.b64encode(username.encode('utf-8')) 43 | # encrypted_password = base64.b64encode(password.encode('utf-8')) 44 | 45 | return encrypted_username, encrypted_password 46 | 47 | 48 | def get_cookies(): 49 | # 首页取 randomstr,依次经过 MD5、SHA1 加密后得到 cookies 中的 passport_e 50 | response_index = session.get(url=index_url, headers=headers) 51 | tree = etree.HTML(response_index.text) 52 | random_str = tree.xpath("//input[@id='J_randomstr']/@value")[0] 53 | random_str_md5 = hashlib.md5(random_str.encode()).hexdigest() 54 | passport_e = execjs.compile(hqew_js).call('SHA1Encrypt', random_str_md5 + 'hqew') 55 | 56 | # 访问首页取 cookies 中的 Hqew_SessionId 57 | cookies_index = response_index.cookies.get_dict() 58 | session_id = cookies_index['Hqew_SessionId'] 59 | 60 | # 访问 vistor 页面,取 cookies 中的 HQEWVisitor 61 | timestamp_13 = str(int(time.time() * 1000)) 62 | timestamp_10 = str(int(time.time())) 63 | response_vistor = session.get(url=vistor_url % timestamp_13, headers=headers) 64 | cookies_vistor = response_vistor.cookies.get_dict() 65 | vistor = cookies_vistor['HQEWVisitor'] 66 | 67 | # 各项参数组成最后登录需要的 cookies 68 | cookies = { 69 | 'Hqew_SessionId': session_id, 70 | 'HQEWVisitor': vistor, 71 | 'Hm_lvt_9c14e7a660000edd280005fedf9fec5c': timestamp_10, 72 | 'Hm_lpvt_9c14e7a660000edd280005fedf9fec5c': timestamp_10, 73 | 'passport_e': passport_e 74 | } 75 | return cookies 76 | 77 | 78 | def login(encrypted_username, encrypted_password, cookies): 79 | data = { 80 | 'UserName': encrypted_username, 81 | 'PassWord': encrypted_password, 82 | 'ValidateCode': '', 83 | 'LoginType': 0, 84 | 'IsRemember': 0, 85 | 'Source': '' 86 | } 87 | response = session.post(url=login_url, headers=headers, cookies=cookies, data=data) 88 | print(response.json()) 89 | 90 | 91 | def main(): 92 | username = input('请输入登录账号: ') 93 | password = input('请输入登录密码: ') 94 | en_username, en_password = get_encrypted_username_password(username, password) 95 | cookies = get_cookies() 96 | login(en_username, en_password, cookies) 97 | 98 | 99 | if __name__ == '__main__': 100 | main() 101 | -------------------------------------------------------------------------------- /JSReverse/passport_xueyiyun_com/xueyiyun_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: xueyiyun_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import base64 13 | 14 | import execjs 15 | import requests 16 | 17 | 18 | session = requests.session() 19 | login_url = 'https://passport.xueyiyun.com/Login?returnUrl=%2f' 20 | public_key_url = 'https://passport.xueyiyun.com/api/account/rsaPublicKeyToBit' 21 | user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36' 22 | 23 | 24 | def get_rsa_public_key(): 25 | headers = {'User-Agent': user_agent} 26 | public_key = session.get(url=public_key_url, headers=headers).json() 27 | return public_key 28 | 29 | 30 | def get_encrypted_password(rsa_public_key, password): 31 | with open('xueyiyun_encrypt.js', 'r', encoding='utf-8') as f: 32 | xueyiyun_js = f.read() 33 | encrypted_password = execjs.compile(xueyiyun_js).call('getEncryptedCiphertext', rsa_public_key, password) 34 | encrypted_password = base64.b64encode(encrypted_password.encode("utf-8")).decode("utf-8") 35 | return encrypted_password 36 | 37 | 38 | def login(encrypted_password, username): 39 | headers = { 40 | 'User-Agent': user_agent, 41 | 'x-requested-with': 'XMLHttpRequest', 42 | 'origin': 'https://passport.xueyiyun.com', 43 | 'referer': 'https://passport.xueyiyun.com/login' 44 | } 45 | data = { 46 | 'Username': username, 47 | 'Password': encrypted_password, 48 | 'RememberMe': False 49 | } 50 | response = session.post(url=login_url, headers=headers, data=data) 51 | print(response.json()) 52 | 53 | 54 | def main(): 55 | username = input('请输入登录账号: ') 56 | password = input('请输入登录密码: ') 57 | key = get_rsa_public_key() 58 | encrypted_password = get_encrypted_password(key, password) 59 | login(encrypted_password, username) 60 | 61 | 62 | if __name__ == '__main__': 63 | main() 64 | 65 | -------------------------------------------------------------------------------- /JSReverse/passport_yhd_com/yhd_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-10-09 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: yhd_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | login_url = 'https://passport.yhd.com/publicPassport/login.do' 17 | headers = { 18 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36' 19 | } 20 | 21 | 22 | def get_encrypted_data(username, password): 23 | with open('yhd_encrypt.js', 'r', encoding='utf-8') as f: 24 | yhd_js = f.read() 25 | encrypted_data = execjs.compile(yhd_js).call('getEncryptedData', username, password) 26 | return encrypted_data 27 | 28 | 29 | def login(encrypted_data): 30 | data = { 31 | 'credentials.username': encrypted_data['encryptedUsername'], 32 | 'credentials.password': encrypted_data['encryptedPassword'], 33 | 'sig': '', 34 | 'is_jab': True, 35 | 'captchaToken': '', 36 | 'jab_st': 1, 37 | 'loginSource': 1, 38 | 'returnUrl': 'http://www.yhd.com', 39 | 'isAutoLogin': 0, 40 | 'slideData': '' 41 | } 42 | response = requests.post(url=login_url, data=data, headers=headers) 43 | print(response.text) 44 | 45 | 46 | def main(): 47 | username = input('请输入登录账号: ') 48 | password = input('请输入登录密码: ') 49 | encrypted_data = get_encrypted_data(username, password) 50 | login(encrypted_data) 51 | 52 | 53 | if __name__ == '__main__': 54 | main() 55 | -------------------------------------------------------------------------------- /JSReverse/passport_zhihuishu_com/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/JSReverse/passport_zhihuishu_com/code.png -------------------------------------------------------------------------------- /JSReverse/passport_zhihuishu_com/zhihuishu_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-11-29 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: zhihuishu_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import time 13 | import json 14 | import base64 15 | import _thread 16 | import requests 17 | import websocket 18 | from PIL import Image 19 | 20 | 21 | web_socket_url = "wss://appcomm-user.zhihuishu.com/app-commserv-user/websocket?qrToken=%s" 22 | get_login_qr_img_url = "https://passport.zhihuishu.com/qrCodeLogin/getLoginQrImg" 23 | login_url = "https://passport.zhihuishu.com/login" 24 | user_info_url = "https://onlineservice.zhihuishu.com/login/getLoginUserInfo" 25 | 26 | headers = { 27 | "Host": "passport.zhihuishu.com", 28 | "Pragma": "no-cache", 29 | "Referer": "https://passport.zhihuishu.com/login", 30 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36" 31 | } 32 | 33 | qr_token = "" 34 | once_password = "" 35 | uuid = "" 36 | cookie = {} 37 | 38 | 39 | def get_cookies_first(): 40 | response = requests.get(url=login_url, headers=headers) 41 | global cookie 42 | cookie = response.cookies.get_dict() 43 | 44 | 45 | def get_login_qr_img(): 46 | response = requests.get(url=get_login_qr_img_url, headers=headers, cookies=cookie).json() 47 | qr_img = response["img"] 48 | global qr_token 49 | qr_token = response["qrToken"] 50 | with open('code.png', 'wb') as f: 51 | f.write(base64.b64decode(qr_img)) 52 | image = Image.open('code.png') 53 | image.show() 54 | print("请扫描验证码! ") 55 | 56 | 57 | def wss_on_message(ws, message): 58 | print("=============== [message] ===============") 59 | message = json.loads(message) 60 | print(message) 61 | if "扫码成功" in message["msg"]: 62 | global once_password, uuid 63 | once_password = message["oncePassword"] 64 | uuid = message["uuid"] 65 | ws.close() 66 | 67 | 68 | def wss_on_error(ws, error): 69 | print("=============== [error] ===============") 70 | print(error) 71 | ws.close() 72 | 73 | 74 | def wss_on_close(ws, close_status_code, close_msg): 75 | print("=============== [closed] ===============") 76 | print(close_status_code) 77 | print(close_msg) 78 | 79 | 80 | def wss_on_open(ws): 81 | def run(*args): 82 | while True: 83 | ws.send(qr_token) 84 | time.sleep(8) 85 | _thread.start_new_thread(run, (qr_token,)) 86 | 87 | 88 | def wss(): 89 | # websocket.enableTrace(True) # 是否显示连接详细信息 90 | ws = websocket.WebSocketApp( 91 | web_socket_url % qr_token, on_open=wss_on_open, 92 | on_message=wss_on_message, on_error=wss_on_error, 93 | on_close=wss_on_close 94 | ) 95 | ws.run_forever() 96 | 97 | 98 | def get_cookie_second(): 99 | global cookie 100 | params = { 101 | "pwd": once_password, 102 | "service": "https://onlineservice.zhihuishu.com/login/gologin" 103 | } 104 | headers["Host"] = "passport.zhihuishu.com" 105 | headers["Referer"] = "https://passport.zhihuishu.com/login" 106 | response = requests.get(url=login_url, params=params, headers=headers, cookies=cookie, allow_redirects=False) 107 | cookie.update(response.cookies.get_dict()) 108 | location = response.headers.get("Location") 109 | return location 110 | 111 | 112 | def get_cookie_third(location): 113 | global cookie 114 | headers["Host"] = "onlineservice.zhihuishu.com" 115 | headers["Referer"] = "https://passport.zhihuishu.com/" 116 | response = requests.get(url=location, headers=headers, cookies=cookie, allow_redirects=False) 117 | cookie.update(response.cookies.get_dict()) 118 | location = response.headers.get("Location") 119 | return location 120 | 121 | 122 | def get_login_user_info(): 123 | headers["Host"] = "onlineservice.zhihuishu.com" 124 | headers["Origin"] = "https://onlineweb.zhihuishu.com" 125 | headers["Referer"] = "https://onlineweb.zhihuishu.com/" 126 | params = {"time": str(int(time.time() * 1000))} 127 | response = requests.get(url=user_info_url, headers=headers, cookies=cookie, params=params) 128 | print(response.text) 129 | 130 | 131 | def main(): 132 | # 第一次获取 cookie,包含 INGRESSCOOKIE、JSESSIONID、SERVERID、acw_tc 133 | get_cookies_first() 134 | # 获取二维码 135 | get_login_qr_img() 136 | # websocket 扫码登录,返回一次性密码 137 | wss() 138 | # 第二次获取 cookie,更新 SERVERID、获取 CASLOGC、CASTGC 139 | location1 = get_cookie_second() 140 | # 第三次获取 cookie,获取 SESSION 141 | get_cookie_third(location1) 142 | # 获取登录用户信息 143 | get_login_user_info() 144 | 145 | 146 | if __name__ == '__main__': 147 | main() 148 | -------------------------------------------------------------------------------- /JSReverse/spider_wangluozhe_com_challenge_1/challenge_1.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-12-01 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: challenge_1.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | challenge_api = "http://spider.wangluozhe.com/challenge/api/1" 17 | headers = { 18 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 19 | "Cookie": "session=282bc521-992c-451d-a006-3be584ce4509.tReFYhd1ESBPS6phcnS1ehOfWFo", 20 | "Host": "spider.wangluozhe.com", 21 | "Origin": "http://spider.wangluozhe.com", 22 | "Referer": "http://spider.wangluozhe.com/challenge/1", 23 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36", 24 | "X-Requested-With": "XMLHttpRequest" 25 | } 26 | 27 | 28 | def get_signature(): 29 | with open('challenge_1.js', 'r', encoding='utf-8') as f: 30 | ppdai_js = execjs.compile(f.read()) 31 | signature = ppdai_js.call("getSign") 32 | print("signature: ", signature) 33 | return signature 34 | 35 | 36 | def main(): 37 | result = 0 38 | for page in range(1, 101): 39 | data = { 40 | "page": page, 41 | "count": 10, 42 | "_signature": get_signature() 43 | } 44 | response = requests.post(url=challenge_api, headers=headers, data=data).json() 45 | for d in response["data"]: 46 | result += d["value"] 47 | print("结果为: ", result) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() -------------------------------------------------------------------------------- /JSReverse/spider_wangluozhe_com_challenge_2/challenge_2.js: -------------------------------------------------------------------------------- 1 | /* # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-12-10 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: challenge_2.js 8 | # @Software: PyCharm 9 | # ================================== */ 10 | 11 | var hexcase = 0; 12 | var chrsz = 8; 13 | 14 | function hex_sha1(s) { 15 | return binb2hex(core_sha1(AlignSHA1(s))); 16 | } 17 | 18 | function sha1_vm_test() { 19 | return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d"; 20 | } 21 | 22 | function core_sha1(blockArray) { 23 | var x = blockArray; 24 | var w = Array(80); 25 | var a = 1732584173; 26 | var b = -271733877; 27 | var c = -1752584194; 28 | var d = 271733878; 29 | var e = -1009589776; 30 | for (var i = 0; i < x.length; i += 16) { 31 | var olda = a; 32 | var oldb = b; 33 | var oldc = c; 34 | var oldd = d; 35 | var olde = e; 36 | for (var j = 0; j < 80; j++) { 37 | if (j < 16) 38 | w[j] = x[i + j]; 39 | else 40 | w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); 41 | var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j))); 42 | e = d; 43 | d = c; 44 | c = rol(b, 30); 45 | b = a; 46 | a = t; 47 | } 48 | a = safe_add(a, olda); 49 | b = safe_add(b, oldb); 50 | c = safe_add(c, oldc); 51 | d = safe_add(d, oldd); 52 | e = safe_add(e, olde); 53 | } 54 | return new Array(a, b, c, d, e); 55 | } 56 | 57 | function sha1_ft(t, b, c, d) { 58 | if (t < 20) { 59 | return (b & c) | ((~b) & d); 60 | } 61 | if (t < 40) { 62 | return b ^ c ^ d; 63 | } 64 | if (t < 60) { 65 | return (b & c) | (b & d) | (c & d); 66 | } 67 | return b ^ c ^ d; 68 | } 69 | 70 | function sha1_kt(t) { 71 | return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514; 72 | } 73 | 74 | function safe_add(x, y) { 75 | var lsw = (x & 0xFFFF) + (y & 0xFFFF); 76 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 77 | return (msw << 16) | (lsw & 0xFFFF); 78 | } 79 | 80 | function rol(num, cnt) { 81 | return (num << cnt) | (num >>> (32 - cnt)); 82 | } 83 | 84 | function AlignSHA1(str) { 85 | var nblk = ((str.length + 8) >> 6) + 1; 86 | var blks = new Array(nblk * 16); 87 | for (var i = 0; i < nblk * 16; i++) { 88 | blks[i] = 0; 89 | } 90 | for (i = 0; i < str.length; i++) { 91 | blks[i >> 2] |= str.charCodeAt(i) << (24 - (i & 3) * 8); 92 | } 93 | blks[i >> 2] |= 0x80 << (24 - (i & 3) * 8); 94 | blks[nblk * 16 - 1] = str.length * 8; 95 | return blks; 96 | } 97 | 98 | function binb2hex(binarray) { 99 | var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; 100 | var str = ""; 101 | for (var i = 0; i < binarray.length * 4; i++) { 102 | str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) + hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF); 103 | } 104 | return str; 105 | } 106 | 107 | function getSign() { 108 | return hex_sha1(Date.parse(new Date).toString()); 109 | } 110 | 111 | // 测试输出 112 | // console.log(getSign()) 113 | -------------------------------------------------------------------------------- /JSReverse/spider_wangluozhe_com_challenge_2/challenge_2.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-12-10 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: challenge_2.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | challenge_api = "http://spider.wangluozhe.com/challenge/api/2" 17 | 18 | headers = { 19 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 20 | "Cookie": "session=eb2d1c7c-3179-4776-938e-f995478c1ebe.wdC8W9r38z_O97ynvrtBlSEQzPk", 21 | "Host": "spider.wangluozhe.com", 22 | "Origin": "http://spider.wangluozhe.com", 23 | "Referer": "http://spider.wangluozhe.com/challenge/2", 24 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36", 25 | "X-Requested-With": "XMLHttpRequest" 26 | } 27 | 28 | 29 | def get_signature(): 30 | with open('challenge_2.js', 'r', encoding='utf-8') as f: 31 | ppdai_js = execjs.compile(f.read()) 32 | signature = ppdai_js.call("getSign") 33 | print("signature: ", signature) 34 | return signature 35 | 36 | 37 | def main(): 38 | result = 0 39 | for page in range(1, 101): 40 | data = { 41 | "page": page, 42 | "count": 10, 43 | "_signature": get_signature() 44 | } 45 | response = requests.post(url=challenge_api, headers=headers, data=data).json() 46 | for d in response["data"]: 47 | result += d["value"] 48 | print("结果为: ", result) 49 | 50 | 51 | if __name__ == '__main__': 52 | main() 53 | -------------------------------------------------------------------------------- /JSReverse/spider_wangluozhe_com_challenge_3/challenge_3.js: -------------------------------------------------------------------------------- 1 | /* # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-12-13 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: challenge_3.js 8 | # @Software: PyCharm 9 | # ================================== */ 10 | 11 | var CryptoJS = require('crypto-js') 12 | 13 | function encryptByDES(message, key) { 14 | var keyHex = CryptoJS.enc.Utf8.parse(key); 15 | var encrypted = CryptoJS.DES.encrypt(message, keyHex, { 16 | mode: CryptoJS.mode.ECB, 17 | padding: CryptoJS.pad.Pkcs7 18 | }); 19 | return encrypted.ciphertext.toString(); 20 | } 21 | 22 | function getSign() { 23 | var message = "http://spider.wangluozhe.com/challenge/3"; 24 | message = message + '|' + Date.parse(new Date()).toString(); 25 | var key = Date.parse(new Date()).toString(); 26 | return encryptByDES(message, key); 27 | } 28 | 29 | // 测试输出 30 | // console.log(getSign()) 31 | -------------------------------------------------------------------------------- /JSReverse/spider_wangluozhe_com_challenge_3/challenge_3.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-12-13 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: challenge_3.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | challenge_api = "http://spider.wangluozhe.com/challenge/api/3" 17 | headers = { 18 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 19 | "Cookie": "session=eb2d1c7c-3179-4776-938e-f995478c1ebe.wdC8W9r38z_O97ynvrtBlSEQzPk", 20 | "Host": "spider.wangluozhe.com", 21 | "Origin": "http://spider.wangluozhe.com", 22 | "Referer": "http://spider.wangluozhe.com/challenge/2", 23 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36", 24 | "X-Requested-With": "XMLHttpRequest" 25 | } 26 | 27 | 28 | def get_signature(): 29 | with open('challenge_3.js', 'r', encoding='utf-8') as f: 30 | ppdai_js = execjs.compile(f.read()) 31 | signature = ppdai_js.call("getSign") 32 | print("signature: ", signature) 33 | return signature 34 | 35 | 36 | def main(): 37 | result = 0 38 | for page in range(1, 101): 39 | data = { 40 | "page": page, 41 | "count": 10, 42 | "_signature": get_signature() 43 | } 44 | response = requests.post(url=challenge_api, headers=headers, data=data).json() 45 | for d in response["data"]: 46 | result += d["value"] 47 | print("结果为: ", result) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /JSReverse/spider_wangluozhe_com_challenge_4/challenge_4.js: -------------------------------------------------------------------------------- 1 | /* # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-12-13 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: challenge_4.js 8 | # @Software: PyCharm 9 | # ================================== */ 10 | 11 | var CryptoJS = require('crypto-js') 12 | 13 | let date = Date.parse(new Date()); 14 | window = {}; 15 | 16 | let key_tmp = date * 1234; 17 | // let key_tmp = date * 1244; 18 | let iv_tmp = date * 4321; 19 | // let iv_tmp = date * 4311; 20 | 21 | const key = CryptoJS.enc.Utf8.parse(key_tmp); 22 | var iv = CryptoJS.enc.Utf8.parse(iv_tmp); 23 | (function tmp(date, key, iv) { 24 | function Encrypt(word) { 25 | let srcs = CryptoJS.enc.Utf8.parse(word); 26 | let encrypted = CryptoJS.AES.encrypt(srcs, key, { 27 | iv: iv, 28 | mode: CryptoJS.mode.CBC, 29 | padding: CryptoJS.pad.Pkcs7 30 | }); 31 | return encrypted.ciphertext.toString().toUpperCase(); 32 | } 33 | 34 | window.sign = Encrypt(date); 35 | })(date, key, iv); 36 | 37 | function getSign() { 38 | return window.sign 39 | } 40 | 41 | // 测试输出 42 | // console.log(getSign()) 43 | -------------------------------------------------------------------------------- /JSReverse/spider_wangluozhe_com_challenge_4/challenge_4.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-12-13 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: challenge_4.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | challenge_api = "http://spider.wangluozhe.com/challenge/api/4" 17 | headers = { 18 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 19 | "Cookie": "session=eb2d1c7c-3179-4776-938e-f995478c1ebe.wdC8W9r38z_O97ynvrtBlSEQzPk", 20 | "Host": "spider.wangluozhe.com", 21 | "Origin": "http://spider.wangluozhe.com", 22 | "Referer": "http://spider.wangluozhe.com/challenge/4", 23 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36", 24 | "X-Requested-With": "XMLHttpRequest" 25 | } 26 | 27 | 28 | def get_signature(): 29 | with open('challenge_4.js', 'r', encoding='utf-8') as f: 30 | ppdai_js = execjs.compile(f.read()) 31 | signature = ppdai_js.call("getSign") 32 | print("signature: ", signature) 33 | return signature 34 | 35 | 36 | def main(): 37 | result = 0 38 | for page in range(1, 101): 39 | data = { 40 | "page": page, 41 | "count": 10, 42 | "_signature": get_signature() 43 | } 44 | response = requests.post(url=challenge_api, headers=headers, data=data).json() 45 | for d in response["data"]: 46 | result += d["value"] 47 | print("结果为: ", result) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /JSReverse/spider_wangluozhe_com_challenge_6/challenge_6.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-12-20 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: challenge_6.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | challenge_api = "http://spider.wangluozhe.com/challenge/api/6" 17 | headers = { 18 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 19 | "Cookie": "session=eb2d1c7c-3179-4776-938e-f995478c1ebe.wdC8W9r38z_O97ynvrtBlSEQzPk; v=A0ljXUrQTfK4UjBNHUpAlhwCWH6glj1Yp4thXOu-xd5tGGdoM-ZNmDfacSh4", 20 | "Host": "spider.wangluozhe.com", 21 | "Origin": "http://spider.wangluozhe.com", 22 | "Referer": "http://spider.wangluozhe.com/challenge/6", 23 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36", 24 | "X-Requested-With": "XMLHttpRequest" 25 | } 26 | 27 | 28 | def get_hexin_v(): 29 | with open('challenge_6.js', 'r', encoding='utf-8') as f: 30 | wlz_js = execjs.compile(f.read()) 31 | hexin_v = wlz_js.call("getHexinV") 32 | print("hexin-v: ", hexin_v) 33 | return hexin_v 34 | 35 | 36 | def main(): 37 | result = 0 38 | for page in range(1, 101): 39 | data = { 40 | "page": page, 41 | "count": 10, 42 | } 43 | headers["hexin-v"] = get_hexin_v() 44 | response = requests.post(url=challenge_api, headers=headers, data=data).json() 45 | for d in response["data"]: 46 | result += d["value"] 47 | print("结果为: ", result) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /JSReverse/store_steampowered_com/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/JSReverse/store_steampowered_com/code.png -------------------------------------------------------------------------------- /JSReverse/store_steampowered_com/steampowered_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-20 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: steampowered_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import time 13 | 14 | import execjs 15 | import requests 16 | from PIL import Image 17 | 18 | 19 | index_url = 'https://store.steampowered.com/login' 20 | login_url = 'https://store.steampowered.com/login/dologin/' 21 | get_rsa_key_url = 'https://store.steampowered.com/login/getrsakey/' 22 | render_captcha_url = 'https://store.steampowered.com/login/rendercaptcha/' 23 | refresh_captcha_url = 'https://store.steampowered.com/login/refreshcaptcha/' 24 | 25 | headers = { 26 | 'Host': 'store.steampowered.com', 27 | 'Origin': 'https://store.steampowered.com', 28 | 'Referer': 'https://store.steampowered.com/login', 29 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 30 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 31 | } 32 | session = requests.session() 33 | 34 | 35 | def get_cookies(): 36 | response = session.get(url=index_url, headers=headers) 37 | cookies = response.cookies.get_dict() 38 | print(cookies) 39 | return cookies 40 | 41 | 42 | def get_captcha(cookies): 43 | # 首先获取 gid 44 | data = {'donotcache': str(int(time.time() * 1000))} 45 | refresh_captcha_response = session.post(url=refresh_captcha_url, data=data, cookies=cookies, headers=headers) 46 | gid = refresh_captcha_response.json()['gid'] 47 | 48 | # 携带 gid 获取验证码 49 | params = {'gid': gid} 50 | render_captcha_response = session.get(url=render_captcha_url, params=params, cookies=cookies, headers=headers) 51 | 52 | with open('code.png', 'wb') as f: 53 | f.write(render_captcha_response.content) 54 | image = Image.open('code.png') 55 | image.show() 56 | captcha = input('请输入验证码: ') 57 | return captcha, gid 58 | 59 | 60 | def get_rsa_key(username, cookies): 61 | data = { 62 | 'donotcache': str(int(time.time() * 1000)), 63 | 'username': username 64 | } 65 | response = session.post(url=get_rsa_key_url, data=data, cookies=cookies, headers=headers).json() 66 | print(response) 67 | return response 68 | 69 | 70 | def get_encrypted_password(password, rsa_key_dict): 71 | with open('steampowered_encrypt.js', 'r', encoding='utf-8') as f: 72 | steampowered_js = f.read() 73 | encrypted_password = execjs.compile(steampowered_js).call('getEncryptedPassword', password, rsa_key_dict) 74 | print(encrypted_password) 75 | return encrypted_password 76 | 77 | 78 | def login(username, encrypted_password, cookies, rsa_key_dict, captcha, gid): 79 | data = { 80 | 'donotcache': str(int(time.time() * 1000)), 81 | 'password': encrypted_password, 82 | 'username': username, 83 | 'twofactorcode': '', 84 | 'emailauth': '', 85 | 'loginfriendlyname': '', 86 | 'captchagid': gid, 87 | 'captcha_text': captcha, 88 | 'emailsteamid': '', 89 | 'rsatimestamp': rsa_key_dict['timestamp'], 90 | 'remember_login': False, 91 | # 'tokentype': '-1' 92 | } 93 | print(data) 94 | response = session.post(url=login_url, data=data, cookies=cookies, headers=headers) 95 | print(response.text) 96 | 97 | 98 | def main(): 99 | username = input('请输入登录账号: ') 100 | password = input('请输入登录密码: ') 101 | 102 | # 获取 cookies 103 | cookies = get_cookies() 104 | 105 | # 获取验证码和 gid 106 | captcha, gid = get_captcha(cookies) 107 | 108 | # 获取 RSA 加密所需 key 等信息 109 | rsa_key_dict = get_rsa_key(username, cookies) 110 | 111 | # 获取加密后的密码 112 | encrypted_password = get_encrypted_password(password, rsa_key_dict) 113 | 114 | # 携带 用户名、加密后的密码、cookies、验证码等登录 115 | login(username, encrypted_password, cookies, rsa_key_dict, captcha, gid) 116 | 117 | 118 | if __name__ == '__main__': 119 | main() 120 | -------------------------------------------------------------------------------- /JSReverse/tenhou_net/tenhou.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: tenhou.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | 14 | 15 | url = 'https://tenhou.net/2/?q=336m237p2479s167z3s' 16 | 17 | 18 | def main(): 19 | q = url.split('=')[1] 20 | with open('tenhou_decrypt.js', 'r', encoding='utf-8') as f: 21 | tenhou_js = f.read() 22 | data = execjs.compile(tenhou_js).call('fa', q) 23 | print(data) 24 | 25 | 26 | if __name__ == '__main__': 27 | main() 28 | -------------------------------------------------------------------------------- /JSReverse/tianaw_95505_cn/tianaw_95505_encrypt.js: -------------------------------------------------------------------------------- 1 | // 引用 crypto-js 加密模块 2 | var CryptoJS = require('crypto-js') 3 | 4 | function getJsonKey(l, privaKey) { 5 | var n = CryptoJS.enc.Utf8.parse(privaKey), 6 | t = CryptoJS.enc.Utf8.parse(privaKey), 7 | e = CryptoJS.enc.Utf8.parse(l), 8 | a = CryptoJS.AES.encrypt(e, n, { 9 | iv: t, 10 | mode: CryptoJS.mode.CBC, 11 | padding: CryptoJS.pad.Pkcs7 12 | }); 13 | return CryptoJS.enc.Base64.stringify(a.ciphertext) 14 | } 15 | 16 | function getPrivaKey(l) { 17 | l = l || 32; 18 | for (var n = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678", t = n.length, e = "", a = 0; a < l; a++) 19 | e += n.charAt(Math.floor(Math.random() * t)); 20 | return e 21 | } 22 | 23 | 24 | // 测试样例 25 | // var data = '{"body":{"loginMethod":"1","name":"13593335454","password":"123321111"},"head":{"userCode":null,"channelCode":"101","transTime":1627356016051,"transToken":"","customerId":null,"transSerialNumber":""}}' 26 | // var privaKey = getPrivaKey(16) 27 | // var jsonKey = getJsonKey(data, privaKey) 28 | // console.log(privaKey) 29 | // console.log(jsonKey) -------------------------------------------------------------------------------- /JSReverse/tianaw_95505_cn/tianaw_95505_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: tianaw_95505_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import time 13 | import json 14 | import base64 15 | 16 | import execjs 17 | import requests 18 | from Cryptodome.PublicKey import RSA 19 | from Cryptodome.Cipher import PKCS1_v1_5 20 | 21 | 22 | login_url = 'https://tianaw.95505.cn/tacpc/tiananapp/customer_login/taPcLogin' 23 | with open('tianaw_95505_encrypt.js', 'r', encoding='utf-8') as f: 24 | tianaw_95505_js = f.read() 25 | 26 | 27 | def get_priva_key(): 28 | priva_key = execjs.compile(tianaw_95505_js).call('getPrivaKey', 16) 29 | return priva_key 30 | 31 | 32 | def get_json_key(priva_key, username, password): 33 | time_now = str(int(time.time() * 1000)) 34 | data = { 35 | "body": { 36 | "loginMethod": "1", 37 | "name": username, 38 | "password": password 39 | }, 40 | "head": { 41 | "userCode": None, 42 | "channelCode": "101", 43 | "transTime": time_now, 44 | "transToken": "", 45 | "customerId": None, 46 | "transSerialNumber": "" 47 | } 48 | } 49 | data_str = json.dumps(data) 50 | json_key = execjs.compile(tianaw_95505_js).call('getJsonKey', data_str, priva_key) 51 | print(json_key) 52 | return json_key 53 | 54 | 55 | def get_header_key(priva_key): 56 | public_key = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAM1xhOWaThSMpfxFsjV5YaWOFHt+6RvS+zH2Pa47VVr8PkZYnRaaKKy2MYBuEh7mZfM/R1dUXTgu0gp6VTNeNQkCAwEAAQ==" 57 | # 导入公钥 58 | rsa_key = RSA.import_key(base64.b64decode(public_key)) 59 | # 生成对象 60 | rsa_object = PKCS1_v1_5.new(rsa_key) 61 | # 加密 62 | header_key = base64.b64encode(rsa_object.encrypt(priva_key.encode(encoding="utf-8"))) 63 | return header_key 64 | 65 | 66 | def login(header_key, json_key): 67 | data = {'jsonKey': json_key} 68 | headers = { 69 | 'key': header_key, 70 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', 71 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"' 72 | } 73 | response = requests.post(url=login_url, headers=headers, params=data, data=data) 74 | print(response.text) 75 | 76 | 77 | def main(): 78 | username = input('请输入登录账号: ') 79 | if len(username) < 11: 80 | print('账号不正确!') 81 | return 82 | password = input('请输入登录密码: ') 83 | if len(password) < 8: 84 | print('密码不正确!') 85 | return 86 | 87 | # 获取 priva key 88 | priva_key = get_priva_key() 89 | 90 | # 获取 json key 91 | json_key = get_json_key(priva_key, username, password) 92 | 93 | # 获取 header 里面的 key,由 priva key 经过 RSA 加密得到 94 | header_key = get_header_key(priva_key) 95 | 96 | # 携带两个 key 登录 97 | login(header_key, json_key) 98 | 99 | 100 | if __name__ == '__main__': 101 | main() 102 | -------------------------------------------------------------------------------- /JSReverse/uac_10010_com/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/JSReverse/uac_10010_com/code.png -------------------------------------------------------------------------------- /JSReverse/uis_nbu_edu_cn/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/JSReverse/uis_nbu_edu_cn/code.png -------------------------------------------------------------------------------- /JSReverse/uis_nbu_edu_cn/uis_nbu_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: uis_nbu_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | from PIL import Image 15 | from lxml import etree 16 | 17 | 18 | login_url = 'https://uis.nbu.edu.cn/authserver/login' 19 | ver_code_url = 'https://uis.nbu.edu.cn/authserver/captcha.html' 20 | headers = { 21 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', 22 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"' 23 | } 24 | session = requests.session() 25 | 26 | 27 | def get_parameter(): 28 | response = session.get(url=login_url, headers=headers) 29 | tree = etree.HTML(response.text) 30 | lt = tree.xpath("//div[@tabid='01']//input[@name='lt']/@value")[0] 31 | dllt = tree.xpath("//div[@tabid='01']//input[@name='dllt']/@value") 32 | execution = tree.xpath("//div[@tabid='01']//input[@name='execution']/@value") 33 | event_id = tree.xpath("//div[@tabid='01']//input[@name='_eventId']/@value") 34 | rm_shown = tree.xpath("//div[@tabid='01']//input[@name='rmShown']/@value") 35 | encrypt_salt = tree.xpath("//div[@tabid='01']//input[@id='pwdDefaultEncryptSalt']/@value")[0] 36 | parameter = { 37 | 'lt': lt, 38 | 'dllt': dllt, 39 | 'execution': execution, 40 | 'event_id': event_id, 41 | 'rm_shown': rm_shown, 42 | 'encrypt_salt': encrypt_salt 43 | } 44 | return parameter 45 | 46 | 47 | def get_encrypted_password(parameter, password): 48 | encrypt_salt = parameter['encrypt_salt'] 49 | with open('uis_nbu_encrypt.js', 'r', encoding='utf-8') as f: 50 | nbu_js = f.read() 51 | encrypted_pwd = execjs.compile(nbu_js).call('getEncryptedPassword', password, encrypt_salt) 52 | return encrypted_pwd 53 | 54 | 55 | def get_verification_code(): 56 | response = session.get(url=ver_code_url, headers=headers) 57 | with open('code.png', 'wb') as f: 58 | f.write(response.content) 59 | image = Image.open('code.png') 60 | image.show() 61 | code = input('请输入验证码: ') 62 | return code 63 | 64 | 65 | def login(parameter, encrypted_password, code, username): 66 | data = { 67 | 'username': username, 68 | 'password': encrypted_password, 69 | 'captchaResponse': code, 70 | 'lt': parameter['lt'], 71 | 'dllt': parameter['dllt'], 72 | 'execution': parameter['execution'], 73 | '_eventId': parameter['event_id'], 74 | 'rmShown': parameter['rm_shown'] 75 | } 76 | response = session.post(url=login_url, headers=headers, data=data) 77 | print(response.text) 78 | 79 | 80 | def main(): 81 | username = input('请输入登录账号: ') 82 | password = input('请输入登录密码: ') 83 | param = get_parameter() 84 | encrypted_password = get_encrypted_password(param, password) 85 | ver_code = get_verification_code() 86 | login(param, encrypted_password, ver_code, username) 87 | 88 | 89 | if __name__ == '__main__': 90 | main() 91 | -------------------------------------------------------------------------------- /JSReverse/unicom_trip_133_cn/unicom_trip.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: unicom_trip.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | # 流入 17 | source_top_url = 'https://unicom_trip.133.cn/api/v1/city/source-top/%s?date=%s' 18 | flight_route_arr_url = 'https://unicom_trip.133.cn/api/v1/city/flight-route/%s?date=%s&type=arr' 19 | train_route_arr_url = 'https://unicom_trip.133.cn/api/v1/city/train-route/%s?date=%s&type=arr' 20 | 21 | # 流出 22 | trip_top_url = 'https://unicom_trip.133.cn/api/v1/city/trip-top/%s?date=%s' 23 | flight_route_dep_url = 'https://unicom_trip.133.cn/api/v1/city/flight-route/%s?date=%s&type=dep' 24 | train_route_dep_url = 'https://unicom_trip.133.cn/api/v1/city/train-route/%s?date=%s&type=dep' 25 | 26 | all_url = [ 27 | source_top_url, flight_route_arr_url, train_route_arr_url, 28 | trip_top_url, flight_route_dep_url, train_route_dep_url 29 | ] 30 | 31 | 32 | def get_encrypted_data(city, date): 33 | headers = { 34 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Mobile Safari/537.36' 35 | } 36 | encrypted_data = [] 37 | for u in all_url: 38 | data = requests.get(url=u % (city, date), headers=headers).text 39 | encrypted_data.append(data) 40 | return encrypted_data 41 | 42 | 43 | def get_decrypted_data(encrypted_data): 44 | with open('unicom_trip_decrypt.js', 'r', encoding='utf-8') as f: 45 | unicom_trip_133_cn_js = f.read() 46 | all_encrypted_data = [] 47 | for d in encrypted_data: 48 | data = execjs.compile(unicom_trip_133_cn_js).call('dataDecode', d) 49 | all_encrypted_data.append(data) 50 | return all_encrypted_data 51 | 52 | 53 | def main(): 54 | """ 55 | 城市可以输入汉字,也可以输入城市代码 56 | 城市代码:https://unicom_trip.133.cn/api/v1/province-all,同样需要解密处理 57 | """ 58 | city = '北京市' 59 | date = '20210713' 60 | encrypted_data = get_encrypted_data(city, date) 61 | decrypted_data = get_decrypted_data(encrypted_data) 62 | print('查询城市: ', city) 63 | print('流入来源城市: ', decrypted_data[0]) 64 | print('流入方向飞机路线: ', decrypted_data[1]) 65 | print('流入方向火车路线: ', decrypted_data[2]) 66 | print('流出方向线路: ', decrypted_data[3]) 67 | print('流出方向飞机路线: ', decrypted_data[4]) 68 | print('流出方向火车路线: ', decrypted_data[5]) 69 | 70 | 71 | if __name__ == '__main__': 72 | main() 73 | 74 | -------------------------------------------------------------------------------- /JSReverse/unicom_trip_133_cn/unicom_trip_decrypt.js: -------------------------------------------------------------------------------- 1 | var CryptoJS = require('crypto-js') 2 | 3 | function Base64() { 4 | 5 | // private property 6 | _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 7 | 8 | // public method for encoding 9 | this.encode = function (input) { 10 | var output = ""; 11 | var chr1, chr2, chr3, enc1, enc2, enc3, enc4; 12 | var i = 0; 13 | input = _utf8_encode(input); 14 | while (i < input.length) { 15 | chr1 = input.charCodeAt(i++); 16 | chr2 = input.charCodeAt(i++); 17 | chr3 = input.charCodeAt(i++); 18 | enc1 = chr1 >> 2; 19 | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 20 | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 21 | enc4 = chr3 & 63; 22 | if (isNaN(chr2)) { 23 | enc3 = enc4 = 64; 24 | } else if (isNaN(chr3)) { 25 | enc4 = 64; 26 | } 27 | output = output + 28 | _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + 29 | _keyStr.charAt(enc3) + _keyStr.charAt(enc4); 30 | } 31 | return output; 32 | } 33 | 34 | // public method for decoding 35 | this.decode = function (input) { 36 | var output = ""; 37 | var chr1, chr2, chr3; 38 | var enc1, enc2, enc3, enc4; 39 | var i = 0; 40 | input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 41 | while (i < input.length) { 42 | enc1 = _keyStr.indexOf(input.charAt(i++)); 43 | enc2 = _keyStr.indexOf(input.charAt(i++)); 44 | enc3 = _keyStr.indexOf(input.charAt(i++)); 45 | enc4 = _keyStr.indexOf(input.charAt(i++)); 46 | chr1 = (enc1 << 2) | (enc2 >> 4); 47 | chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 48 | chr3 = ((enc3 & 3) << 6) | enc4; 49 | output = output + String.fromCharCode(chr1); 50 | if (enc3 != 64) { 51 | output = output + String.fromCharCode(chr2); 52 | } 53 | if (enc4 != 64) { 54 | output = output + String.fromCharCode(chr3); 55 | } 56 | } 57 | output = _utf8_decode(output); 58 | return output; 59 | } 60 | 61 | // private method for UTF-8 encoding 62 | _utf8_encode = function (string) { 63 | string = string.replace(/\r\n/g, "\n"); 64 | var utftext = ""; 65 | for (var n = 0; n < string.length; n++) { 66 | var c = string.charCodeAt(n); 67 | if (c < 128) { 68 | utftext += String.fromCharCode(c); 69 | } else if ((c > 127) && (c < 2048)) { 70 | utftext += String.fromCharCode((c >> 6) | 192); 71 | utftext += String.fromCharCode((c & 63) | 128); 72 | } else { 73 | utftext += String.fromCharCode((c >> 12) | 224); 74 | utftext += String.fromCharCode(((c >> 6) & 63) | 128); 75 | utftext += String.fromCharCode((c & 63) | 128); 76 | } 77 | 78 | } 79 | return utftext; 80 | } 81 | 82 | // private method for UTF-8 decoding 83 | _utf8_decode = function (utftext) { 84 | var string = ""; 85 | var i = 0; 86 | var c = c1 = c2 = 0; 87 | while (i < utftext.length) { 88 | c = utftext.charCodeAt(i); 89 | if (c < 128) { 90 | string += String.fromCharCode(c); 91 | i++; 92 | } else if ((c > 191) && (c < 224)) { 93 | c2 = utftext.charCodeAt(i + 1); 94 | string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); 95 | i += 2; 96 | } else { 97 | c2 = utftext.charCodeAt(i + 1); 98 | c3 = utftext.charCodeAt(i + 2); 99 | string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 100 | i += 3; 101 | } 102 | } 103 | return string; 104 | } 105 | } 106 | 107 | function dataDecode(data) { 108 | var base = new Base64(); 109 | var d = JSON.parse(base.decode(data)); 110 | var key = 'UVJgCE+OFIff3hK5BT5sPBbGZzjR6FwntjSCwOA9tUQ='; 111 | var key1 = CryptoJS.enc.Base64.parse(key); 112 | var iv1 = CryptoJS.enc.Base64.parse(d.iv); 113 | var decrypted = CryptoJS.AES.decrypt(d.value, key1, { 114 | iv: iv1, 115 | mode: CryptoJS.mode.CBC, 116 | padding: CryptoJS.pad.Pkcs7 117 | }); 118 | var d = decrypted.toString(CryptoJS.enc.Utf8); 119 | return JSON.parse(d); 120 | } 121 | 122 | // 测试样例 123 | // var data = "eyJpdiI6IkdkMlYzXC9tYVwvSzRwcldHN1h2dlFIdz09IiwidmFsdWUiOiJhNUdzSVN3UXJpYllQRW5FQ2RyS0x6OHRVeFZcL1VSeDlNeVl3Q09cL0d1Q3c9IiwibWFjIjoiOTVlMWE0Mjk3MGY1YmIwY2E4MGQxNWI0OThlMjlhYjY0ZTcyMmZkMjg0MGI3YjczODk1ODJiZWU2MWNiNzc5ZCJ9" 124 | // console.log(dataDecode(data)) 125 | -------------------------------------------------------------------------------- /JSReverse/wap_10086_cn/10086_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-04 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: 10086_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import time 13 | 14 | import execjs 15 | import requests 16 | 17 | 18 | login_url = 'https://login.10086.cn/login.htm' 19 | send_code_url = 'https://login.10086.cn/sendRandomCodeAction.action' 20 | chk_number_url = 'https://login.10086.cn/chkNumberAction.action' 21 | user_agent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1' 22 | session = requests.session() 23 | 24 | 25 | def get_encrypted_data(username, password): 26 | with open('10086_encrypt.js', 'r', encoding='utf-8') as f: 27 | exec_js = execjs.compile(f.read()) 28 | encrypted_username = exec_js.call('getEncryptedData', username) 29 | encrypted_password = exec_js.call('getEncryptedData', password) 30 | return encrypted_username, encrypted_password 31 | 32 | 33 | def chk_number(encrypted_username): 34 | data = { 35 | 'userName': encrypted_username, 36 | 'loginMode': '03', 37 | 'channelID': '10000' 38 | } 39 | headers = {'User-Agent': user_agent} 40 | response = session.post(url=chk_number_url, data=data, headers=headers).text 41 | if response == 'false': 42 | raise Exception('账号非移动账号!') 43 | 44 | 45 | def send_code(encrypted_username): 46 | data = { 47 | 'userName': encrypted_username, 48 | 'type': '01', 49 | 'channelID': '12022' 50 | } 51 | headers = {'User-Agent': user_agent} 52 | response = session.post(url=send_code_url, data=data, headers=headers).text 53 | # print(response) 54 | 55 | 56 | def login(encrypted_password, encrypted_username, code): 57 | data = { 58 | 'accountType': '01', 59 | 'pwdType': '01', 60 | 'account': encrypted_username, 61 | 'password': encrypted_password, 62 | 'smsPwd': code, 63 | 'backUrl': 'https://wap.10086.cn/hb/index_270_270.html?s=1', 64 | 'rememberMe': '0', 65 | 'channelID': '12022', 66 | 'loginMode': '03', 67 | 'protocol': 'https:', 68 | 'timestamp': str(int(time.time() * 1000)) 69 | } 70 | headers = { 71 | 'User-Agent': user_agent, 72 | 'Host': 'login.10086.cn', 73 | 'Origin': 'https://login.10086.cn', 74 | 'X-Requested-With': 'XMLHttpRequest', 75 | 'Referer': 'https://login.10086.cn/html/login/touch.html?channelID=12022&backUrl=https://wap.10086.cn/hb/index_270_270.html?s=1' 76 | } 77 | response = session.post(url=login_url, data=data, headers=headers) 78 | print(response.text) 79 | 80 | 81 | def main(): 82 | username = input('请输入账号: ') 83 | password = input('请输入密码: ') 84 | encrypted_username, encrypted_password = get_encrypted_data(username, password) 85 | chk_number(encrypted_username) 86 | send_code(encrypted_username) 87 | code = input('请输入验证码: ') 88 | login(encrypted_username, encrypted_password, code) 89 | 90 | 91 | if __name__ == '__main__': 92 | main() 93 | -------------------------------------------------------------------------------- /JSReverse/web_ewt360_com/ewt360_encrypt.js: -------------------------------------------------------------------------------- 1 | CryptoJS = require("crypto-js") 2 | 3 | const key = CryptoJS.enc.Utf8.parse("20171109124536982017110912453698"); 4 | const iv = CryptoJS.enc.Utf8.parse('2017110912453698'); //十六位十六进制数作为密钥偏移量 5 | 6 | function getEncryptedPassword(word) { 7 | let srcs = CryptoJS.enc.Utf8.parse(word); 8 | let encrypted = CryptoJS.AES.encrypt(srcs, key, { 9 | iv: iv, 10 | mode: CryptoJS.mode.CBC, 11 | padding: CryptoJS.pad.Pkcs7 12 | }); 13 | return encrypted.ciphertext.toString().toUpperCase(); 14 | } 15 | 16 | // 测试样例 17 | // console.log(getEncryptedPassword("123457")) 18 | -------------------------------------------------------------------------------- /JSReverse/web_ewt360_com/ewt360_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-10-09 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: ewt360_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import time 13 | import hashlib 14 | 15 | import execjs 16 | import requests 17 | 18 | 19 | login_url = 'https://gateway.ewt360.com/api/authcenter/v2/oauth/login/account' 20 | session = requests.session() 21 | 22 | 23 | def get_sign(): 24 | timestamp = str(int(time.time()*1000)) 25 | sign = hashlib.md5((timestamp + 'bdc739ff2dcf').encode(encoding='utf-8')).hexdigest().upper() 26 | return sign 27 | 28 | 29 | def get_encrypted_parameter(password): 30 | with open('ewt360_encrypt.js', 'r', encoding='utf-8') as f: 31 | ewt360_js = f.read() 32 | encrypted_password = execjs.compile(ewt360_js).call('getEncryptedPassword', password) 33 | return encrypted_password 34 | 35 | 36 | def login(sign, username, encrypted_password): 37 | headers = { 38 | 'sign': sign, 39 | 'timestamp': str(int(time.time()*1000)), 40 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 41 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 42 | } 43 | data = { 44 | 'autoLogin': True, 45 | 'password': encrypted_password, 46 | 'platform': 1, 47 | 'userName': username 48 | } 49 | response = session.post(url=login_url, headers=headers, json=data) 50 | print(response.json()) 51 | 52 | 53 | def main(): 54 | username = input('请输入登录账号: ') 55 | password = input('请输入登录密码: ') 56 | sign = get_sign() 57 | encrypted_password = get_encrypted_parameter(password) 58 | login(sign, username, encrypted_password) 59 | 60 | 61 | if __name__ == '__main__': 62 | main() 63 | -------------------------------------------------------------------------------- /JSReverse/www_15yunmall_com/15yunmall_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-20 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: 15yunmall_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | from lxml import etree 16 | from PIL import Image 17 | 18 | 19 | index_url = 'http://www.15yunmall.com/pc/login/index' 20 | login_url = 'http://www.15yunmall.com/pc/login/check' 21 | code_url = 'http://www.15yunmall.com/very/code.html' 22 | 23 | headers = { 24 | 'Host': 'www.15yunmall.com', 25 | 'Referer': 'http://www.15yunmall.com/', 26 | 'Origin': 'http://www.15yunmall.com', 27 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36' 28 | } 29 | session = requests.session() 30 | 31 | 32 | def get_encrypted_password(password): 33 | with open('15yunmall_encrypt.js', 'r', encoding='utf-8') as f: 34 | yunmall_js = f.read() 35 | encrypted_password = execjs.compile(yunmall_js).call('getEncryptedPassword', password) 36 | return encrypted_password 37 | 38 | 39 | def get_csrf_token_cookie(): 40 | response = session.get(url=index_url, headers=headers) 41 | tree = etree.HTML(response.text) 42 | csrf_token = tree.xpath("//input[@name='_csrfToken']/@value")[0] 43 | cookies = response.cookies.get_dict() 44 | # print(csrf_token, cookies) 45 | return csrf_token, cookies 46 | 47 | 48 | def get_very_code(cookies): 49 | response = session.get(url=code_url, cookies=cookies, headers=headers) 50 | with open('code.png', 'wb') as f: 51 | f.write(response.content) 52 | image = Image.open('code.png') 53 | image.show() 54 | very_code = input('请输入验证码: ') 55 | return very_code 56 | 57 | 58 | def login(csrf_token, very_code, cookies, username, encrypted_password): 59 | data = { 60 | 'u[loginType]': 'name', 61 | 'u[phone]': username, 62 | 'u[password]': encrypted_password, 63 | 'u[veryCode]': very_code, 64 | 'u[token]': '', 65 | '_csrfToken': csrf_token 66 | } 67 | header_info = { 68 | 'X-Requested-With': 'XMLHttpRequest', 69 | } 70 | headers.update(header_info) 71 | response = session.post(url=login_url, data=data, cookies=cookies, headers=headers) 72 | response.encoding = 'utf-8-sig' 73 | response_code = response.text 74 | # print(response_code) 75 | status_code = { 76 | '31': '恭喜,登陆成功。', 77 | '32': '登陆失败。', 78 | '33': '用户名或密码错误。', 79 | '35': '该用户已被管理员锁定。', 80 | '311': '该账号已绑定设备,请在绑定的设备登陆。', 81 | '20001': '验证码填写错误!' 82 | } 83 | try: 84 | print(status_code[response_code]) 85 | except KeyError: 86 | print('请求超时!') 87 | 88 | 89 | def main(): 90 | username = input('请输入登录账号: ') 91 | password = input('请输入登录密码: ') 92 | if len(password) > 32: 93 | raise Exception('请输入正确的密码!') 94 | encrypted_password = get_encrypted_password(password) 95 | csrf_token, cookies = get_csrf_token_cookie() 96 | very_code = get_very_code(cookies) 97 | login(csrf_token, very_code, cookies, username, encrypted_password) 98 | 99 | 100 | if __name__ == '__main__': 101 | main() 102 | -------------------------------------------------------------------------------- /JSReverse/www_15yunmall_com/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/JSReverse/www_15yunmall_com/code.png -------------------------------------------------------------------------------- /JSReverse/www_37_com/37_encrypt.js: -------------------------------------------------------------------------------- 1 | var ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 2 | function __rsa(str) { 3 | var out, i, len; 4 | var c1, c2, c3; 5 | len = str.length; 6 | i = 0; 7 | out = ""; 8 | while (i < len) { 9 | c1 = str.charCodeAt(i++) & 0xff; 10 | if (i == len) { 11 | out += ch.charAt(c1 >> 2); 12 | out += ch.charAt((c1 & 0x3) << 4); 13 | out += "=="; 14 | break 15 | } 16 | c2 = str.charCodeAt(i++); 17 | if (i == len) { 18 | out += ch.charAt(c1 >> 2); 19 | out += ch.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)); 20 | out += ch.charAt((c2 & 0xF) << 2); 21 | out += "="; 22 | break 23 | } 24 | c3 = str.charCodeAt(i++); 25 | out += ch.charAt(c1 >> 2); 26 | out += ch.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)); 27 | out += ch.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)); 28 | out += ch.charAt(c3 & 0x3F) 29 | } 30 | return out 31 | } 32 | 33 | function getEncryptedPassword(a) { 34 | var maxPos = ch.length - 2 35 | , w = []; 36 | for (i = 0; i < 15; i++) { 37 | w.push(ch.charAt(Math.floor(Math.random() * maxPos))); 38 | if (i === 7) { 39 | w.push(a.substr(0, 3)) 40 | } 41 | if (i === 12) { 42 | w.push(a.substr(3)) 43 | } 44 | } 45 | return __rsa(w.join("")) 46 | } 47 | 48 | // 测试样例 49 | // console.log(getEncryptedPassword("34343434")) 50 | -------------------------------------------------------------------------------- /JSReverse/www_37_com/37_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-04 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: 37_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | import time 12 | import random 13 | 14 | import execjs 15 | import requests 16 | 17 | 18 | login_url = 'https://my.37.com/api/login.php' 19 | 20 | 21 | def get_encrypted_password(password): 22 | with open('37_encrypt.js', 'r', encoding='utf-8') as f: 23 | www_37_js = f.read() 24 | encrypted_pwd = execjs.compile(www_37_js).call('getEncryptedPassword', password) 25 | return encrypted_pwd 26 | 27 | 28 | def login(username, encrypted_password): 29 | timestamp = str(int(time.time() * 1000)) 30 | jsonp = '' 31 | for _ in range(20): 32 | jsonp += str(random.randint(0, 9)) 33 | callback = 'jQuery' + jsonp + '_' + timestamp 34 | params = { 35 | 'callback': callback, 36 | 'action': 'login', 37 | 'login_account': username, 38 | 'password': encrypted_password, 39 | 'ajax': 0, 40 | 'remember_me': 1, 41 | 'save_state': 1, 42 | 'ltype': 1, 43 | 'tj_from': 100, 44 | 's': 1, 45 | 'tj_way': 1, 46 | '_': timestamp 47 | } 48 | headers = { 49 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', 50 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"' 51 | } 52 | response = requests.post(url=login_url, headers=headers, params=params) 53 | print(response.text) 54 | 55 | 56 | def main(): 57 | username = input('请输入登录账号: ') 58 | password = input('请输入登录密码: ') 59 | encrypted_password = get_encrypted_password(password) 60 | login(username, encrypted_password) 61 | 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /JSReverse/www_airasia_com/flightstatus.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-10-09 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: flightstatus.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import requests 13 | 14 | 15 | status_url = 'https://k.apiairasia.com/flightstatus/status/od/v3/' 16 | 17 | 18 | def get_flight_status(departure, destination, date): 19 | headers = { 20 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36', 21 | 'authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJMQ0FLaWhpbUxlTjZ3a1FYU2FhRTgyZTh0ZDUwM3NZUiIsImlhdCI6MTUzMzY5NzU5NSwiZXhwIjoxODQ5MzE2Nzk1LCJhdWQiOiJGbGlnaHQgU3RhdHVzIiwic3ViIjoiRmxpZ2h0IFN0YXR1cyJ9._M8lPMqvBYW20NcjeUyb0iQRrUYSjIWhGwJeDY4Apns' 22 | } 23 | complete_url = status_url + departure + '/' + destination + '/' + date 24 | response = requests.get(url=complete_url, headers=headers) 25 | print(response.text) 26 | 27 | 28 | if __name__ == '__main__': 29 | departure = input('请输入出发地代码:') 30 | destination = input('请输入目的地代码:') 31 | date = input('请输入日期(例如:29/09/2021):') 32 | 33 | # departure = 'MFM' 34 | # destination = 'KUL' 35 | # date = '29/09/2021' 36 | get_flight_status(departure, destination, date) 37 | -------------------------------------------------------------------------------- /JSReverse/www_appmiu_com/appmiu.js: -------------------------------------------------------------------------------- 1 | var e = function () { 2 | for (var t = arguments.length, n = Array(t), r = 0; r < t; r++) 3 | n[r] = arguments[r]; 4 | var e = n.length 5 | , i = "string" == typeof n[e - 1] ? n[e - 1] : "Assert Error" 6 | , o = !0 7 | , u = !1 8 | , c = void 0; 9 | try { 10 | for (var f, a = n[Symbol.iterator](); !(o = (f = a.next()).done); o = !0) { 11 | if (!f.value) 12 | throw new Error(i) 13 | } 14 | } catch (t) { 15 | u = !0, 16 | c = t 17 | } finally { 18 | try { 19 | !o && a.return && a.return() 20 | } finally { 21 | if (u) 22 | throw c 23 | } 24 | } 25 | } 26 | , i = function () { 27 | return Math.random() >= .5 28 | } 29 | , o = function (t) { 30 | var n = /[A-Za-z0-9\-\_\.\!\~\*\'\(\)]/g 31 | , r = t.replace(n, function (t) { 32 | return t.codePointAt(0).toString(16) 33 | }); 34 | return encodeURIComponent(r).replace(/%/g, "").toUpperCase() 35 | } 36 | , u = function (t) { 37 | e("string" == typeof t, "utfs Error"); 38 | var n = t.length; 39 | e(0 == (1 & n)); 40 | for (var r = [], i = 0; i < n; i++) 41 | 0 == (1 & i) && r.push("%"), 42 | r.push(t[i]); 43 | return decodeURIComponent(r.join("")) 44 | } 45 | , c = function (t) { 46 | e("string" == typeof t); 47 | var n = [] 48 | , r = !0 49 | , o = !1 50 | , u = void 0; 51 | try { 52 | for (var c, f = t[Symbol.iterator](); !(r = (c = f.next()).done); r = !0) { 53 | var a = c.value 54 | , s = Number.parseInt(a, 16); 55 | s < 10 ? n.push(s) : i() ? (n.push(10), 56 | n.push(s - 10)) : (n.push(11), 57 | n.push(s - 6)) 58 | } 59 | } catch (t) { 60 | o = !0, 61 | u = t 62 | } finally { 63 | try { 64 | !r && f.return && f.return() 65 | } finally { 66 | if (o) 67 | throw u 68 | } 69 | } 70 | return n 71 | } 72 | , f = function (t) { 73 | e(t instanceof Array); 74 | for (var n = [], r = t.length, i = 0; i < r;) 75 | t[i] < 10 ? n.push(t[i]) : 10 === t[i] ? (i++, 76 | n.push(t[i] + 10)) : (i++, 77 | n.push(t[i] + 6)), 78 | i++; 79 | return n.map(function (t) { 80 | return t.toString(16).toUpperCase() 81 | }).join("") 82 | } 83 | , a = function (t) { 84 | return t.map(function (t) { 85 | return h[2 * t] + h[2 * t + 1] 86 | }).join("") 87 | } 88 | , s = function (t) { 89 | var n = [] 90 | , r = !0 91 | , i = !1 92 | , o = void 0; 93 | try { 94 | for (var c, a = t[Symbol.iterator](); !(r = (c = a.next()).done); r = !0) { 95 | var s = c.value 96 | , l = h.indexOf(s); 97 | -1 !== l && (1 & l || n.push(l >> 1)) 98 | } 99 | } catch (t) { 100 | i = !0, 101 | o = t 102 | } finally { 103 | try { 104 | !r && a.return && a.return() 105 | } finally { 106 | if (i) 107 | throw o 108 | } 109 | } 110 | var v = f(n); 111 | e(0 == (1 & v.length)); 112 | var p = void 0; 113 | try { 114 | p = u(v) 115 | } catch (t) { 116 | throw t 117 | } 118 | return p 119 | } 120 | , h = "富强民主文明和谐自由平等公正法治爱国敬业诚信友善" 121 | 122 | function encrypt(t) { 123 | return a(c(o(t))) 124 | } 125 | 126 | function decrypt(t) { 127 | return s(t) 128 | } 129 | 130 | 131 | // 测试样例 132 | // console.log(encrypt("1234")) 133 | // console.log(decrypt("和谐民主和谐文明和谐和谐和谐自由")) 134 | -------------------------------------------------------------------------------- /JSReverse/www_aqistudy_cn/main.js: -------------------------------------------------------------------------------- 1 | /* # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2022-01-05 4 | # @Author : ITBOB 5 | # @Blog : www.itbob.cn 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: main.js 8 | # @Software: PyCharm 9 | # ================================== */ 10 | 11 | var CryptoJS = require("crypto-js"); 12 | 13 | var BASE64 = { 14 | encrypt: function (text) { 15 | // var b = new Base64(); 16 | // return b.encode(text); 17 | return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(text)) 18 | }, 19 | decrypt: function (text) { 20 | // var b = new Base64(); 21 | // return b.decode(text); 22 | return CryptoJS.enc.Base64.parse(text).toString(CryptoJS.enc.Utf8) 23 | } 24 | }; 25 | 26 | var DES = { 27 | encrypt: function (text, key, iv) { 28 | var secretkey = (CryptoJS.MD5(key).toString()).substr(0, 16); 29 | var secretiv = (CryptoJS.MD5(iv).toString()).substr(24, 8); 30 | secretkey = CryptoJS.enc.Utf8.parse(secretkey); 31 | secretiv = CryptoJS.enc.Utf8.parse(secretiv); 32 | var result = CryptoJS.DES.encrypt(text, secretkey, { 33 | iv: secretiv, 34 | mode: CryptoJS.mode.CBC, 35 | padding: CryptoJS.pad.Pkcs7 36 | }); 37 | return result.toString(); 38 | }, 39 | decrypt: function (text, key, iv) { 40 | var secretkey = (CryptoJS.MD5(key).toString()).substr(0, 16); 41 | var secretiv = (CryptoJS.MD5(iv).toString()).substr(24, 8); 42 | secretkey = CryptoJS.enc.Utf8.parse(secretkey); 43 | secretiv = CryptoJS.enc.Utf8.parse(secretiv); 44 | var result = CryptoJS.DES.decrypt(text, secretkey, { 45 | iv: secretiv, 46 | mode: CryptoJS.mode.CBC, 47 | padding: CryptoJS.pad.Pkcs7 48 | }); 49 | return result.toString(CryptoJS.enc.Utf8); 50 | } 51 | }; 52 | 53 | var AES = { 54 | encrypt: function (text, key, iv) { 55 | var secretkey = (CryptoJS.MD5(key).toString()).substr(16, 16); 56 | var secretiv = (CryptoJS.MD5(iv).toString()).substr(0, 16); 57 | // console.log('real key:', secretkey); 58 | // console.log('real iv:', secretiv); 59 | secretkey = CryptoJS.enc.Utf8.parse(secretkey); 60 | secretiv = CryptoJS.enc.Utf8.parse(secretiv); 61 | var result = CryptoJS.AES.encrypt(text, secretkey, { 62 | iv: secretiv, 63 | mode: CryptoJS.mode.CBC, 64 | padding: CryptoJS.pad.Pkcs7 65 | }); 66 | return result.toString(); 67 | }, 68 | decrypt: function (text, key, iv) { 69 | var secretkey = (CryptoJS.MD5(key).toString()).substr(16, 16); 70 | var secretiv = (CryptoJS.MD5(iv).toString()).substr(0, 16); 71 | secretkey = CryptoJS.enc.Utf8.parse(secretkey); 72 | secretiv = CryptoJS.enc.Utf8.parse(secretiv); 73 | var result = CryptoJS.AES.decrypt(text, secretkey, { 74 | iv: secretiv, 75 | mode: CryptoJS.mode.CBC, 76 | padding: CryptoJS.pad.Pkcs7 77 | }); 78 | return result.toString(CryptoJS.enc.Utf8); 79 | } 80 | }; 81 | 82 | function getDecryptedData(data, AES_KEY_1, AES_IV_1, DES_KEY_1, DES_IV_1) { 83 | data = AES.decrypt(data, AES_KEY_1, AES_IV_1); 84 | data = DES.decrypt(data, DES_KEY_1, DES_IV_1); 85 | data = BASE64.decrypt(data); 86 | return data; 87 | } 88 | 89 | function ObjectSort(obj) { 90 | var newObject = {}; 91 | Object.keys(obj).sort().map(function (key) { 92 | newObject[key] = obj[key]; 93 | }); 94 | return newObject; 95 | } 96 | 97 | function getRequestParam(method, obj, appId) { 98 | var clienttype = 'WEB'; 99 | var timestamp = new Date().getTime() 100 | var param = { 101 | appId: appId, 102 | method: method, 103 | timestamp: timestamp, 104 | clienttype: clienttype, 105 | object: obj, 106 | secret: CryptoJS.MD5(appId + method + timestamp + clienttype + JSON.stringify(ObjectSort(obj))).toString() 107 | }; 108 | param = BASE64.encrypt(JSON.stringify(param)); 109 | return param; 110 | } 111 | 112 | function getRequestAESParam(requestMethod, requestCity, appId, AES_KEY_2, AES_IV_2){ 113 | var param = getRequestParam(requestMethod, requestCity, appId); 114 | return AES.encrypt(param, AES_KEY_2, AES_IV_2); 115 | } 116 | 117 | function getRequestDESParam(requestMethod, requestCity, appId, DES_KEY_2, DES_IV_2){ 118 | var param = getRequestParam(requestMethod, requestCity, appId); 119 | return DES.encrypt(param, DES_KEY_2, DES_IV_2); 120 | } 121 | 122 | // var requestMethod = "GETDATA" 123 | // var requestCity = {city: '北京'} 124 | // var appId = "49f79420965a848068868c54864ecb7e" 125 | // var AES_KEY_1 = "aIFJGOW9DT1EisD8" 126 | // var AES_IV_1 = "bwXuHH56NEn3XnFG" 127 | // var AES_KEY_2 = "dHonRXYPhwlvKzKL" 128 | // var AES_IV_2 = "fTF0B4Jtu3SeOY4C" 129 | // var DES_KEY_1 = "h2rXliiTDehlHsM5" 130 | // var DES_IV_1 = "xy7OT0UjDQUoMYrJ" 131 | // var DES_KEY_2 = "drnan951bHwbiZUN" 132 | // var DES_IV_2 = "fdkV46lJBJvDdnjX" 133 | // // var data = "43NQGXU3q99BncxQY0SUrR/4H+Pae9nL4RaGh6yDDbcZclwl5e2xhLfv8yhYupHdy6EoFqIY5EBy8rEZ7K+ldO51XJ4uDIhp1QxA8GB3GyjtCOlOdgfIqcJqR9US0uG56XSmfJDQH9Y6MAsvr5mEqg==" 134 | // // console.log(getDecryptedData(data, AES_KEY_1, AES_IV_1, DES_KEY_1, DES_IV_1)) 135 | // console.log(getRequestParam(requestMethod, requestCity, appId, DES_KEY_2, DES_IV_2)) 136 | -------------------------------------------------------------------------------- /JSReverse/www_aqistudy_cn/main.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2022-01-05 4 | # @Author : ITBOB 5 | # @Blog : www.itbob.cn 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: main.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import re 13 | import json 14 | import base64 15 | import execjs 16 | import requests 17 | 18 | 19 | index_url = "https://www.aqistudy.cn/" 20 | aqistudy_api = "https://www.aqistudy.cn/apinew/aqistudyapi.php" 21 | city_realtime_url = "https://www.aqistudy.cn/html/city_realtime.php?v=2.3" 22 | headers = { 23 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" 24 | } 25 | 26 | 27 | def get_encrypted_js_url(): 28 | response = requests.get(url=city_realtime_url, headers=headers) 29 | encrypt_js_name = re.findall(r"(js/encrypt_.*?)\">", response.text)[0] 30 | encrypted_js_url = index_url + encrypt_js_name 31 | # print(encrypted_js_url) 32 | return encrypted_js_url 33 | 34 | 35 | def get_decrypted_js(encrypted_js_url): 36 | """ 37 | :param encrypted_js_url: encrypt_xxxxxx.js 的地址 38 | :return: 解密后的 JS 39 | """ 40 | decrypted_js = requests.get(url=encrypted_js_url, headers=headers).text 41 | flag = True 42 | while flag: 43 | if "eval(function" in decrypted_js: 44 | # 需要执行 eval 45 | print("需要执行 eval!") 46 | replace_js = decrypted_js.replace("eval(function", "(function") 47 | decrypted_js = execjs.eval(replace_js) 48 | elif "dswejwehxt(" in decrypted_js: 49 | # 需要 base64 解码 50 | base64_num = decrypted_js.count("dswejwehxt(") 51 | print("需要 %s 次 base64 解码!" % base64_num) 52 | decrypted_js = re.findall(r"\('(.*?)'\)", decrypted_js)[0] 53 | num = 0 54 | while base64_num > num: 55 | decrypted_js = base64.b64decode(decrypted_js).decode() 56 | num += 1 57 | else: 58 | # 得到明文 59 | flag = False 60 | # print(decrypted_js) 61 | return decrypted_js 62 | 63 | 64 | def get_key_iv_appid(decrypted_js): 65 | """ 66 | :param decrypted_js: 解密后的 encrypt_xxxxxx.js 67 | :return: 请求必须的一些参数 68 | """ 69 | key_iv = re.findall(r'const.*?"(.*?)";', decrypted_js) 70 | app_id = re.findall(r"var appId.*?'(.*?)';", decrypted_js) 71 | request_data_name = re.findall(r"aqistudyapi.php.*?data.*?{(.*?):", decrypted_js, re.DOTALL) 72 | 73 | # 判断 param 是 AES 加密还是 DES 加密还是没有加密 74 | if "AES.encrypt(param" in decrypted_js: 75 | request_param_encrypt = "AES" 76 | elif "DES.encrypt(param" in decrypted_js: 77 | request_param_encrypt = "DES" 78 | else: 79 | request_param_encrypt = "NO" 80 | 81 | key_iv_appid = { 82 | # key 和 iv 的位置和原来 js 里的是一样的 83 | "aes_key_1": key_iv[0], 84 | "aes_iv_1": key_iv[1], 85 | "aes_key_2": key_iv[2], 86 | "aes_iv_2": key_iv[3], 87 | "des_key_1": key_iv[4], 88 | "des_iv_1": key_iv[5], 89 | "des_key_2": key_iv[6], 90 | "des_iv_2": key_iv[7], 91 | "app_id": app_id[0], 92 | # 发送请求的 data 的键名 93 | "request_data_name": request_data_name[0].strip(), 94 | # 发送请求的 data 值需要哪种加密 95 | "request_param_encrypt": request_param_encrypt 96 | } 97 | # print(key_iv_appid) 98 | return key_iv_appid 99 | 100 | 101 | def get_data(key_iv_appid): 102 | """ 103 | :param key_iv_appid: get_key_iv_appid() 方法返回的值 104 | """ 105 | request_method = "GETDATA" 106 | request_city = {"city": "北京"} 107 | with open('main.js', 'r', encoding='utf-8') as f: 108 | execjs_ = execjs.compile(f.read()) 109 | 110 | # 根据不同加密方式调用不同方法获取请求加密的 param 参数 111 | request_param_encrypt = key_iv_appid["request_param_encrypt"] 112 | if request_param_encrypt == "AES": 113 | param = execjs_.call( 114 | 'getRequestAESParam', request_method, request_city, 115 | key_iv_appid["app_id"], key_iv_appid["aes_key_2"], key_iv_appid["aes_iv_2"] 116 | ) 117 | elif request_param_encrypt == "DES": 118 | param = execjs_.call( 119 | 'getRequestDESParam', request_method, request_city, 120 | key_iv_appid["app_id"], key_iv_appid["des_key_2"], key_iv_appid["des_iv_2"] 121 | ) 122 | else: 123 | param = execjs_.call('getRequestParam', request_method, request_city, key_iv_appid["app_id"]) 124 | data = { 125 | key_iv_appid["request_data_name"]: param 126 | } 127 | response = requests.post(url=aqistudy_api, headers=headers, data=data).text 128 | # print(response) 129 | 130 | # 对获取的加密数据解密 131 | decrypted_data = execjs_.call( 132 | 'getDecryptedData', response, 133 | key_iv_appid["aes_key_1"], key_iv_appid["aes_iv_1"], 134 | key_iv_appid["des_key_1"], key_iv_appid["des_iv_1"] 135 | ) 136 | print(json.loads(decrypted_data)) 137 | 138 | 139 | def main(): 140 | # 获取 encrypt_ 开头的 JS 文件地址 141 | encrypted_js_url = get_encrypted_js_url() 142 | # 获取 encrypt_ 开头的 JS 文件并对其进行 eval 和 base64 解密 143 | decrypted_js = get_decrypted_js(encrypted_js_url) 144 | # 获取 JS 里面的各种 key、iv、appId,判断 param 是 AES 还是 DES 还是没有 145 | key_iv_appid = get_key_iv_appid(decrypted_js) 146 | # 测试获取数据,以北京为例 147 | get_data(key_iv_appid) 148 | 149 | 150 | if __name__ == '__main__': 151 | main() 152 | -------------------------------------------------------------------------------- /JSReverse/www_gm99_com/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/JSReverse/www_gm99_com/code.png -------------------------------------------------------------------------------- /JSReverse/www_gm99_com/gm99_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-10-09 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: gm99_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import re 13 | import json 14 | import time 15 | import random 16 | import base64 17 | from urllib import parse 18 | 19 | import execjs 20 | import requests 21 | from PIL import Image 22 | from Cryptodome.PublicKey import RSA 23 | from Cryptodome.Cipher import PKCS1_v1_5 24 | 25 | login_url = 'https://passport.gm99.com/login/login3' 26 | verify_image_url = 'https://passport.gm99.com/verify_image' 27 | check_code_url = 'https://passport.gm99.com/ajax/check_code' 28 | 29 | headers = { 30 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 31 | } 32 | session = requests.session() 33 | 34 | 35 | def get_jquery(): 36 | jsonp = '' 37 | for _ in range(21): 38 | jsonp += str(random.randint(0, 9)) 39 | jquery = 'jQuery' + jsonp + '_' 40 | return jquery 41 | 42 | 43 | def get_dict_from_jquery(text): 44 | result = re.findall(r'\((.*?)\)', text)[0] 45 | return json.loads(result) 46 | 47 | 48 | def get_encrypted_password_by_javascript(password): 49 | # 两个 JavaScript 脚本,两种方法均可 50 | with open('gm99_encrypt.js', 'r', encoding='utf-8') as f: 51 | # with open('gm99_encrypt_2.js', 'r', encoding='utf-8') as f: 52 | exec_js = f.read() 53 | encrypted_password = execjs.compile(exec_js).call('getEncryptedPassword', password) 54 | return encrypted_password 55 | 56 | 57 | def get_encrypted_password_by_python(password): 58 | timestamp = str(int(time.time() * 1000)) 59 | encrypted_object = timestamp + "|" + password 60 | public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDq04c6My441Gj0UFKgrqUhAUg+kQZeUeWSPlAU9fr4HBPDldAeqzx1UR92KJHuQh/zs1HOamE2dgX9z/2oXcJaqoRIA/FXysx+z2YlJkSk8XQLcQ8EBOkp//MZrixam7lCYpNOjadQBb2Ot0U/Ky+jF2p+Ie8gSZ7/u+Wnr5grywIDAQAB" 61 | rsa_key = RSA.import_key(base64.b64decode(public_key)) # 导入读取到的公钥 62 | cipher = PKCS1_v1_5.new(rsa_key) # 生成对象 63 | encrypted_password = base64.b64encode(cipher.encrypt(encrypted_object.encode(encoding="utf-8"))) 64 | encrypted_password = parse.quote(encrypted_password) 65 | return encrypted_password 66 | 67 | 68 | def get_verify_code(): 69 | response = session.get(url=verify_image_url, headers=headers) 70 | with open('code.png', 'wb') as f: 71 | f.write(response.content) 72 | image = Image.open('code.png') 73 | image.show() 74 | code = input('请输入图片验证码: ') 75 | return code 76 | 77 | 78 | def check_code(code): 79 | timestamp = str(int(time.time() * 1000)) 80 | params = { 81 | 'callback': get_jquery() + timestamp, 82 | 'ckcode': code, 83 | '_': timestamp, 84 | } 85 | response = session.get(url=check_code_url, params=params, headers=headers) 86 | result = get_dict_from_jquery(response.text) 87 | if result['result'] == 1: 88 | pass 89 | else: 90 | raise Exception('验证码输入错误!') 91 | 92 | 93 | def login(username, encrypted_password, code): 94 | timestamp = str(int(time.time() * 1000)) 95 | params = { 96 | 'callback': get_jquery() + timestamp, 97 | 'encrypt': 1, 98 | 'uname': username, 99 | 'password': encrypted_password, 100 | 'remember': 'checked', 101 | 'ckcode': code, 102 | '_': timestamp 103 | } 104 | response = session.get(url=login_url, params=params, headers=headers) 105 | result = get_dict_from_jquery(response.text) 106 | print(result) 107 | 108 | 109 | def main(): 110 | # 测试账号:15434947408,密码:iXqC@aJt8fi@VwV 111 | username = input('请输入登录账号: ') 112 | password = input('请输入登录密码: ') 113 | 114 | # 获取加密后的密码,使用 Python 或者 JavaScript 实现均可 115 | encrypted_password = get_encrypted_password_by_javascript(password) 116 | # encrypted_password = get_encrypted_password_by_python(password) 117 | 118 | # 获取验证码 119 | code = get_verify_code() 120 | 121 | # 校验验证码 122 | check_code(code) 123 | 124 | # 登录 125 | login(username, encrypted_password, code) 126 | 127 | 128 | if __name__ == '__main__': 129 | main() 130 | -------------------------------------------------------------------------------- /JSReverse/www_hfax_com/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/JSReverse/www_hfax_com/code.png -------------------------------------------------------------------------------- /JSReverse/www_hfax_com/hfax_encrypt.js: -------------------------------------------------------------------------------- 1 | // 引用 crypto-js 加密模块 2 | var CryptoJS = require('crypto-js') 3 | 4 | function getEncryptedPassword(t) { 5 | return CryptoJS.MD5(t + "TuD00Iqz4ge7gzIe2rmjSAFFKtaIBmnr8S").toString() 6 | } 7 | 8 | // 测试样例 9 | // console.log(getEncryptedPassword("123123131")) -------------------------------------------------------------------------------- /JSReverse/www_hfax_com/hfax_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: hfax_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import re 13 | import base64 14 | import hashlib 15 | 16 | import execjs 17 | import requests 18 | from PIL import Image 19 | 20 | 21 | index_url = 'https://www.hfax.com/login.html' 22 | login_page_url = 'https://www.hfax.com/pc-api/loginPageUrl' 23 | login_url = 'https://www.hfax.com/pc-api/user/login' 24 | pre_login_url = 'https://www.hfax.com/pc-api/common/imageCode/login' 25 | 26 | headers = { 27 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 28 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 29 | } 30 | session = requests.session() 31 | 32 | 33 | def get_cookies(): 34 | response_index = session.get(url=index_url, headers=headers) 35 | cookies_index_dict = response_index.cookies.get_dict() 36 | # print(cookies_index_dict) 37 | 38 | response_page = session.get(url=login_page_url, headers=headers, cookies=cookies_index_dict) 39 | cookies_page_dict = response_page.cookies.get_dict() 40 | # print(cookies_page_dict) 41 | 42 | cookies_index_dict.update(cookies_page_dict) 43 | return cookies_index_dict 44 | 45 | 46 | def get_code_data(cookies): 47 | response = session.get(url=pre_login_url, headers=headers, cookies=cookies).json() 48 | # print(response) 49 | return response 50 | 51 | 52 | def get_code(code_base64): 53 | result = re.search("data:image/(?P.*?);base64,(?P.*)", code_base64, re.DOTALL) 54 | code_type = result.groupdict().get('img_type') 55 | code_data = result.groupdict().get('img_data') 56 | code_data = base64.urlsafe_b64decode(code_data) 57 | code_name = 'code.%s' % code_type 58 | with open(code_name, 'wb') as f: 59 | f.write(code_data) 60 | image = Image.open(code_name) 61 | image.show() 62 | code_value = input('请输入验证码: ') 63 | return code_value 64 | 65 | 66 | def get_encrypted_password(password): 67 | # 使用 JS 获取加密后的密码 68 | # with open('hfax_encrypt.js', 'r', encoding='utf-8') as f: 69 | # hfax_js = f.read() 70 | # encrypted_password = execjs.compile(hfax_js).call('getEncryptedPassword', password) 71 | # return encrypted_password 72 | 73 | # 使用 Python 实现密码的加密 74 | md5 = hashlib.md5() 75 | md5.update((password + 'TuD00Iqz4ge7gzIe2rmjSAFFKtaIBmnr8S').encode()) 76 | encrypted_password = md5.hexdigest() 77 | return encrypted_password 78 | 79 | 80 | def login(code, code_token, username, encrypted_password, cookies): 81 | data = { 82 | 'imgCode': code, 83 | 'imgToken': code_token, 84 | 'password': encrypted_password, 85 | 'username': username 86 | } 87 | response = session.post(url=login_url, headers=headers, json=data, cookies=cookies) 88 | print(response.json()) 89 | 90 | 91 | def main(): 92 | username = input('请输入登录账号: ') 93 | password = input('请输入登录密码: ') 94 | 95 | # 通过两个链接获取 cookies 96 | cookies = get_cookies() 97 | 98 | # 通过预登陆链接,获取验证码 token 和 base64 字符串 99 | parameter = get_code_data(cookies) 100 | 101 | # 分别取验证码的 token 和 base64 字符串 102 | code_base64 = parameter['data']['base64Str'] 103 | code_token = parameter['data']['token'] 104 | 105 | # 通过 base64 字符串保存并显示验证码 106 | code = get_code(code_base64) 107 | 108 | # 获取加密后的密码 109 | encrypted_password = get_encrypted_password(password) 110 | 111 | # 携带验证码、验证码 token、用户名、加密后的密码以及 cookies 登录 112 | login(code, code_token, username, encrypted_password, cookies) 113 | 114 | 115 | if __name__ == '__main__': 116 | main() 117 | -------------------------------------------------------------------------------- /JSReverse/www_hnzwfw_gov_cn/encrypt.js: -------------------------------------------------------------------------------- 1 | /* # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2022-01-11 4 | # @Author : ITBOB 5 | # @Blog : www.itbob.cn 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: encrypt.js 8 | # @Software: PyCharm 9 | # ================================== */ 10 | 11 | JSEncrypt = require("jsencrypt") 12 | 13 | function encrypt(pwd){ 14 | var key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsgDq4OqxuEisnk2F0EJFmw4xKa5IrcqEYHvqxPs2CHEg2kolhfWA2SjNuGAHxyDDE5MLtOvzuXjBx/5YJtc9zj2xR/0moesS+Vi/xtG1tkVaTCba+TV+Y5C61iyr3FGqr+KOD4/XECu0Xky1W9ZmmaFADmZi7+6gO9wjgVpU9aLcBcw/loHOeJrCqjp7pA98hRJRY+MML8MK15mnC4ebooOva+mJlstW6t/1lghR8WNV8cocxgcHHuXBxgns2MlACQbSdJ8c6Z3RQeRZBzyjfey6JCCfbEKouVrWIUuPphBL3OANfgp0B+QG31bapvePTfXU48TYK0M5kE+8LgbbWQIDAQAB"; 15 | var encrypt = new JSEncrypt(); 16 | encrypt.setPublicKey(key); 17 | var encrypted = encrypt.encrypt(pwd); 18 | return encrypted; 19 | } 20 | 21 | // 测试样例 22 | // console.log(encrypt("15555555555")) 23 | -------------------------------------------------------------------------------- /JSReverse/www_hnzwfw_gov_cn/hnzww_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2022-01-11 4 | # @Author : ITBOB 5 | # @Blog : www.itbob.cn 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: hnzww_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | cookies = {} 17 | UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" 18 | 19 | with open("encrypt.js", encoding="utf-8") as f: 20 | js = execjs.compile(f.read()) 21 | 22 | 23 | def csrf_save(): 24 | url = "https://login.hnzwfw.gov.cn/tacs-uc/naturalMan/csrfSave" 25 | headers = {"User-Agent": UA} 26 | response = requests.post(url=url, headers=headers, cookies=cookies).json() 27 | data = response["data"] 28 | return data 29 | 30 | 31 | def get_session(): 32 | url = "https://login.hnzwfw.gov.cn/tacs-uc/login/index" 33 | headers = {"User-Agent": UA} 34 | response = requests.get(url=url, headers=headers) 35 | cookies.update(response.cookies.get_dict()) 36 | 37 | 38 | def get_uuid(): 39 | url = "https://login.hnzwfw.gov.cn/tacs-uc/naturalMan/uploadIdentifier" 40 | headers = { 41 | "User-Agent": UA, 42 | "token": js.call("encrypt", csrf_save()) 43 | } 44 | response = requests.post(url=url, headers=headers, cookies=cookies).json() 45 | uuid = response["data"] 46 | return uuid 47 | 48 | 49 | def ver_code(): 50 | url = "https://login.hnzwfw.gov.cn/tacs-uc/login/verCode" 51 | headers = { 52 | "User-Agent": UA, 53 | "token": js.call("encrypt", csrf_save()) 54 | } 55 | response = requests.post(url=url, headers=headers, cookies=cookies).json() 56 | data = response["data"] 57 | return data 58 | 59 | 60 | def login(phone, pwd, code, uuid): 61 | url = "https://login.hnzwfw.gov.cn/tacs-uc/naturalMan/loginNo" 62 | headers = { 63 | "User-Agent": UA, 64 | "token": js.call("encrypt", csrf_save()) 65 | } 66 | data = { 67 | "backUrl": "", 68 | "loginNo": js.call("encrypt", phone), 69 | "loginPwd": js.call("encrypt", pwd), 70 | "code": code, 71 | "requestUUID": uuid, 72 | "guoBanAuthCode": "" 73 | } 74 | response = requests.post(url=url, headers=headers, cookies=cookies, data=data) 75 | print(response.json()) 76 | 77 | 78 | def main(): 79 | phone = input("请输入账号:") 80 | pwd = input("请输入密码:") 81 | get_session() 82 | uuid = get_uuid() 83 | code = ver_code() 84 | login(phone, pwd, code, uuid) 85 | 86 | 87 | if __name__ == '__main__': 88 | main() 89 | -------------------------------------------------------------------------------- /JSReverse/www_iappstoday_com/iappstoday_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-13 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: iappstoday_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | login_url = 'http://www.iappstoday.com/ajax/login' 17 | 18 | 19 | def get_encrypted_password(password): 20 | with open('iappstoday_encrypt.js', 'r', encoding='utf-8') as f: 21 | iappstoday_js = f.read() 22 | encrypted_password = execjs.compile(iappstoday_js).call('getEncryptedPassword', password) 23 | return encrypted_password 24 | 25 | 26 | def login(username, encrypted_password): 27 | data = { 28 | 'username': username, 29 | 'password': encrypted_password 30 | } 31 | headers = { 32 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36' 33 | } 34 | response = requests.get(url=login_url, data=data, headers=headers).json() 35 | print(response) 36 | 37 | 38 | def main(): 39 | username = input('请输入登录账号: ') 40 | password = input('请输入登录密码: ') 41 | encrypted_pwd = get_encrypted_password(password) 42 | login(username, encrypted_pwd) 43 | 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /JSReverse/www_kuwo_cn/get_reqId.js: -------------------------------------------------------------------------------- 1 | var kuwo; 2 | 3 | !function(e) { 4 | var t = {}; 5 | 6 | function d(n) { 7 | if (t[n]) return t[n].exports; 8 | var r = t[n] = { 9 | i: n, 10 | l: !1, 11 | exports: {} 12 | }; 13 | return e[n].call(r.exports, r, r.exports, d), 14 | r.l = !0, 15 | r.exports 16 | } 17 | 18 | d.n = function(e) { 19 | var n = e && e.__esModule ? 20 | function() { 21 | return e. 22 | default 23 | }: 24 | function() { 25 | return e 26 | }; 27 | return d.d(n, "a", n), 28 | n 29 | }, 30 | d.d = function(e, n, r) { 31 | d.o(e, n) || Object.defineProperty(e, n, { 32 | enumerable: !0, 33 | get: r 34 | }) 35 | }, 36 | d.o = function(object, e) { 37 | return Object.prototype.hasOwnProperty.call(object, e) 38 | } 39 | 40 | kuwo = d 41 | }({ 42 | 109 : function(t, e, n) { 43 | var r, o, l = n(202), 44 | c = n(203), 45 | h = 0, 46 | d = 0; 47 | t.exports = function(t, e, n) { 48 | var i = e && n || 0, 49 | b = e || [], 50 | f = (t = t || {}).node || r, 51 | v = void 0 !== t.clockseq ? t.clockseq: o; 52 | if (null == f || null == v) { 53 | var m = l(); 54 | null == f && (f = r = [1 | m[0], m[1], m[2], m[3], m[4], m[5]]), 55 | null == v && (v = o = 16383 & (m[6] << 8 | m[7])) 56 | } 57 | var y = void 0 !== t.msecs ? t.msecs: (new Date).getTime(), 58 | w = void 0 !== t.nsecs ? t.nsecs: d + 1, 59 | dt = y - h + (w - d) / 1e4; 60 | if (dt < 0 && void 0 === t.clockseq && (v = v + 1 & 16383), (dt < 0 || y > h) && void 0 === t.nsecs && (w = 0), w >= 1e4) throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); 61 | h = y, 62 | d = w, 63 | o = v; 64 | var x = (1e4 * (268435455 & (y += 122192928e5)) + w) % 4294967296; 65 | b[i++] = x >>> 24 & 255, 66 | b[i++] = x >>> 16 & 255, 67 | b[i++] = x >>> 8 & 255, 68 | b[i++] = 255 & x; 69 | var _ = y / 4294967296 * 1e4 & 268435455; 70 | b[i++] = _ >>> 8 & 255, 71 | b[i++] = 255 & _, 72 | b[i++] = _ >>> 24 & 15 | 16, 73 | b[i++] = _ >>> 16 & 255, 74 | b[i++] = v >>> 8 | 128, 75 | b[i++] = 255 & v; 76 | for (var A = 0; A < 6; ++A) b[i + A] = f[A]; 77 | return e || c(b) 78 | } 79 | }, 80 | 202 : function(t, e) { 81 | var n = "undefined" != typeof crypto && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || "undefined" != typeof msCrypto && "function" == typeof window.msCrypto.getRandomValues && msCrypto.getRandomValues.bind(msCrypto); 82 | if (n) { 83 | var r = new Uint8Array(16); 84 | t.exports = function() { 85 | return n(r), 86 | r 87 | } 88 | } else { 89 | var o = new Array(16); 90 | t.exports = function() { 91 | for (var t, i = 0; i < 16; i++) 0 == (3 & i) && (t = 4294967296 * Math.random()), 92 | o[i] = t >>> ((3 & i) << 3) & 255; 93 | return o 94 | } 95 | } 96 | }, 97 | 203 : function(t, e) { 98 | for (var n = [], i = 0; i < 256; ++i) n[i] = (i + 256).toString(16).substr(1); 99 | t.exports = function(t, e) { 100 | var i = e || 0, 101 | r = n; 102 | return [r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]]].join("") 103 | } 104 | } 105 | }) 106 | 107 | function getReqId() { 108 | var l = kuwo(109), 109 | c = kuwo.n(l), 110 | r = c()() 111 | return r 112 | } 113 | 114 | // console.log(getReqId()) 115 | -------------------------------------------------------------------------------- /JSReverse/www_kuwo_cn/get_reqId_2.js: -------------------------------------------------------------------------------- 1 | var kuwo; 2 | 3 | !function (e){ 4 | var t = {}; 5 | 6 | function d(n) { 7 | if (t[n]) return t[n].exports; 8 | var r = t[n] = { 9 | i: n, 10 | l: !1, 11 | exports: {} 12 | }; 13 | return e[n].call(r.exports, r, r.exports, d), 14 | r.l = !0, 15 | r.exports 16 | } 17 | 18 | d.n = function (e) { 19 | var n = e && e.__esModule ? 20 | function () { 21 | return e.default 22 | } : 23 | function () { 24 | return e 25 | }; 26 | return d.d(n, "a", n), 27 | n 28 | }, 29 | d.d = function (e, n, r) { 30 | d.o(e, n) || Object.defineProperty(e, n, { 31 | enumerable: !0, 32 | get: r 33 | }) 34 | }, 35 | d.o = function (object, e) { 36 | return Object.prototype.hasOwnProperty.call(object, e) 37 | } 38 | 39 | kuwo = d 40 | }([ 41 | function (t, e, n) { 42 | var r, o, l = n(1), 43 | c = n(2), 44 | h = 0, 45 | d = 0; 46 | t.exports = function (t, e, n) { 47 | var i = e && n || 0, 48 | b = e || [], 49 | f = (t = t || {}).node || r, 50 | v = void 0 !== t.clockseq ? t.clockseq : o; 51 | if (null == f || null == v) { 52 | var m = l(); 53 | null == f && (f = r = [1 | m[0], m[1], m[2], m[3], m[4], m[5]]), 54 | null == v && (v = o = 16383 & (m[6] << 8 | m[7])) 55 | } 56 | var y = void 0 !== t.msecs ? t.msecs : (new Date).getTime(), 57 | w = void 0 !== t.nsecs ? t.nsecs : d + 1, 58 | dt = y - h + (w - d) / 1e4; 59 | if (dt < 0 && void 0 === t.clockseq && (v = v + 1 & 16383), (dt < 0 || y > h) && void 0 === t.nsecs && (w = 0), w >= 1e4) throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); 60 | h = y, 61 | d = w, 62 | o = v; 63 | var x = (1e4 * (268435455 & (y += 122192928e5)) + w) % 4294967296; 64 | b[i++] = x >>> 24 & 255, 65 | b[i++] = x >>> 16 & 255, 66 | b[i++] = x >>> 8 & 255, 67 | b[i++] = 255 & x; 68 | var _ = y / 4294967296 * 1e4 & 268435455; 69 | b[i++] = _ >>> 8 & 255, 70 | b[i++] = 255 & _, 71 | b[i++] = _ >>> 24 & 15 | 16, 72 | b[i++] = _ >>> 16 & 255, 73 | b[i++] = v >>> 8 | 128, 74 | b[i++] = 255 & v; 75 | for (var A = 0; A < 6; ++A) b[i + A] = f[A]; 76 | return e || c(b) 77 | } 78 | }, 79 | function (t, e) { 80 | var n = "undefined" != typeof crypto && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || "undefined" != typeof msCrypto && "function" == typeof window.msCrypto.getRandomValues && msCrypto.getRandomValues.bind(msCrypto); 81 | if (n) { 82 | var r = new Uint8Array(16); 83 | t.exports = function () { 84 | return n(r), 85 | r 86 | } 87 | } else { 88 | var o = new Array(16); 89 | t.exports = function () { 90 | for (var t, i = 0; i < 16; i++) 0 == (3 & i) && (t = 4294967296 * Math.random()), 91 | o[i] = t >>> ((3 & i) << 3) & 255; 92 | return o 93 | } 94 | } 95 | }, 96 | function (t, e) { 97 | for (var n = [], i = 0; i < 256; ++i) n[i] = (i + 256).toString(16).substr(1); 98 | t.exports = function (t, e) { 99 | var i = e || 0, 100 | r = n; 101 | return [r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]]].join("") 102 | } 103 | } 104 | ]) 105 | 106 | function getReqId() { 107 | var l = kuwo(0), 108 | c = kuwo.n(l), 109 | r = c()() 110 | return r 111 | } 112 | 113 | // console.log(getReqId()) 114 | -------------------------------------------------------------------------------- /JSReverse/www_kuwo_cn/get_reqId_3.js: -------------------------------------------------------------------------------- 1 | var f109 = function(t, e, n) { 2 | var r, o, l = n(1), 3 | c = n(2), 4 | h = 0, 5 | d = 0; 6 | t.exports = function(t, e, n) { 7 | var i = e && n || 0, 8 | b = e || [], 9 | f = (t = t || {}).node || r, 10 | v = void 0 !== t.clockseq ? t.clockseq: o; 11 | if (null == f || null == v) { 12 | var m = l(); 13 | null == f && (f = r = [1 | m[0], m[1], m[2], m[3], m[4], m[5]]), 14 | null == v && (v = o = 16383 & (m[6] << 8 | m[7])) 15 | } 16 | var y = void 0 !== t.msecs ? t.msecs: (new Date).getTime(), 17 | w = void 0 !== t.nsecs ? t.nsecs: d + 1, 18 | dt = y - h + (w - d) / 1e4; 19 | if (dt < 0 && void 0 === t.clockseq && (v = v + 1 & 16383), (dt < 0 || y > h) && void 0 === t.nsecs && (w = 0), w >= 1e4) throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); 20 | h = y, 21 | d = w, 22 | o = v; 23 | var x = (1e4 * (268435455 & (y += 122192928e5)) + w) % 4294967296; 24 | b[i++] = x >>> 24 & 255, 25 | b[i++] = x >>> 16 & 255, 26 | b[i++] = x >>> 8 & 255, 27 | b[i++] = 255 & x; 28 | var _ = y / 4294967296 * 1e4 & 268435455; 29 | b[i++] = _ >>> 8 & 255, 30 | b[i++] = 255 & _, 31 | b[i++] = _ >>> 24 & 15 | 16, 32 | b[i++] = _ >>> 16 & 255, 33 | b[i++] = v >>> 8 | 128, 34 | b[i++] = 255 & v; 35 | for (var A = 0; A < 6; ++A) b[i + A] = f[A]; 36 | return e || c(b) 37 | } 38 | }; 39 | var f202 = function(t, e) { 40 | var n = "undefined" != typeof crypto && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || "undefined" != typeof msCrypto && "function" == typeof window.msCrypto.getRandomValues && msCrypto.getRandomValues.bind(msCrypto); 41 | if (n) { 42 | var r = new Uint8Array(16); 43 | t.exports = function() { 44 | return n(r), 45 | r 46 | } 47 | } else { 48 | var o = new Array(16); 49 | t.exports = function() { 50 | for (var t, i = 0; i < 16; i++) 0 == (3 & i) && (t = 4294967296 * Math.random()), 51 | o[i] = t >>> ((3 & i) << 3) & 255; 52 | return o 53 | } 54 | } 55 | }; 56 | var f203 = function(t, e) { 57 | for (var n = [], i = 0; i < 256; ++i) n[i] = (i + 256).toString(16).substr(1); 58 | t.exports = function(t, e) { 59 | var i = e || 0, 60 | r = n; 61 | return [r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]]].join("") 62 | } 63 | }; 64 | 65 | var e = [f109, f202, f203]; 66 | 67 | function d(n) { 68 | var t = {}; 69 | if (t[n]) return t[n].exports; 70 | var r = t[n] = { 71 | i: n, 72 | l: !1, 73 | exports: {} 74 | }; 75 | return e[n].call(r.exports, r, r.exports, d), 76 | r.l = !0, 77 | r.exports 78 | } 79 | 80 | d.n = function(e) { 81 | var n = e && e.__esModule ? 82 | function() { 83 | return e. 84 | default 85 | }: 86 | function() { 87 | return e 88 | }; 89 | return d.d(n, "a", n), 90 | n 91 | }, 92 | d.d = function(e, n, r) { 93 | d.o(e, n) || Object.defineProperty(e, n, { 94 | enumerable: !0, 95 | get: r 96 | }) 97 | }, 98 | d.o = function(object, e) { 99 | return Object.prototype.hasOwnProperty.call(object, e) 100 | }; 101 | 102 | function getReqId() { 103 | var l = d(0), 104 | c = d.n(l), 105 | r = c()() 106 | return r 107 | } 108 | 109 | // console.log(getReqId()) -------------------------------------------------------------------------------- /JSReverse/www_kuwo_cn/kuwo_search.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-11-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: kuwo_search.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | host = "www.kuwo.cn" 17 | index_url = "http://www.kuwo.cn/search/list" 18 | search_url = "http://www.kuwo.cn/api/www/search/searchMusicBykeyWord" 19 | session = requests.session() 20 | UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" 21 | 22 | 23 | def get_get_req_id(): 24 | with open('get_reqId.js', 'r', encoding='utf-8') as f: 25 | req_id_js = f.read() 26 | req_id = execjs.compile(req_id_js).call('getReqId') 27 | return req_id 28 | 29 | 30 | def get_kw_token(music_name): 31 | headers = {"User-Agent": UA} 32 | params = {"key": music_name} 33 | response = session.get(url=index_url, params=params, headers=headers) 34 | kw_token = response.cookies.get_dict()["kw_token"] 35 | return kw_token 36 | 37 | 38 | def search_music(music_name, req_id, kw_token): 39 | headers = { 40 | "Referer": index_url, 41 | "csrf": kw_token, 42 | "Host": host, 43 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" 44 | } 45 | params = { 46 | "key": music_name, 47 | "httpsStatus": 1, 48 | "pn": 1, 49 | "rn": 30, 50 | "reqId": req_id 51 | } 52 | response = session.get(url=search_url, params=params, headers=headers) 53 | print(response.text) 54 | 55 | 56 | def main(): 57 | music_name = input("请输入音乐名称:") 58 | req_id = get_get_req_id() 59 | kw_token = get_kw_token(music_name) 60 | search_music(music_name, req_id, kw_token) 61 | 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /JSReverse/www_miguvideo_com/miguvideo_login.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: miguvideo_login.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import execjs 13 | import requests 14 | 15 | 16 | login_url = 'https://passport.migu.cn/authn' 17 | public_key_url = 'https://passport.migu.cn/password/publickey' 18 | headers = { 19 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 20 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 21 | } 22 | session = requests.session() 23 | 24 | 25 | def get_public_key(): 26 | response = session.post(url=public_key_url, headers=headers).json() 27 | return response 28 | 29 | 30 | def get_encrypted_parameter(public_key, username, password): 31 | with open('miguvideo_encrypt.js', 'r', encoding='utf-8') as f: 32 | miguvideo_js = f.read() 33 | exec_js = execjs.compile(miguvideo_js) 34 | login_id = exec_js.call('getLoginID', public_key, username) 35 | encrypted_password = exec_js.call('getEncryptedPassword', public_key, password) 36 | finger_print = exec_js.call('getFingerPrint', public_key) 37 | encrypted_parameter = { 38 | 'login_id': login_id, 39 | 'encrypted_password': encrypted_password, 40 | 'finger_print': finger_print['result'], 41 | 'finger_print_detail': finger_print['details'] 42 | } 43 | return encrypted_parameter 44 | 45 | 46 | def login(encrypted_parameter): 47 | data = { 48 | 'sourceID': 203021, 49 | 'appType': 2, 50 | 'relayState': 'login', 51 | 'loginID': encrypted_parameter['login_id'], 52 | 'enpassword': encrypted_parameter['encrypted_password'], 53 | 'captcha': '', 54 | 'imgcodeType': 1, 55 | 'fingerPrint': encrypted_parameter['finger_print'], 56 | 'fingerPrintDetail': encrypted_parameter['finger_print_detail'], 57 | 'isAsync': True 58 | } 59 | response = session.post(url=login_url, headers=headers, data=data) 60 | print(response.json()) 61 | 62 | 63 | def main(): 64 | username = input('请输入登录账号: ') 65 | password = input('请输入登录密码: ') 66 | public_key = get_public_key() 67 | encrypted_parameter = get_encrypted_parameter(public_key, username, password) 68 | login(encrypted_parameter) 69 | 70 | 71 | if __name__ == '__main__': 72 | main() 73 | -------------------------------------------------------------------------------- /JSReverse/www_qimingpian_cn/qimingpian.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: qimingpian.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import json 13 | 14 | import execjs 15 | import requests 16 | 17 | 18 | data_url = 'https://vipapi.qimingpian.com/DataList/productListVip' 19 | 20 | 21 | def get_encrypted_data(): 22 | headers = { 23 | 'Content-Type': 'application/x-www-form-urlencoded', 24 | 'Host': 'vipapi.qimingpian.com', 25 | 'Origin': 'https://www.qimingpian.cn', 26 | 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 27 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 28 | } 29 | data = { 30 | 'time_interval': '', 31 | 'tag': '', 32 | 'tag_type': '', 33 | 'province': '', 34 | 'lunci': '', 35 | 'page': 1, 36 | 'num': 20, 37 | 'unionid': '' 38 | } 39 | encrypted_data = requests.post(url=data_url, headers=headers, data=data) 40 | encrypted_data = encrypted_data.json()['encrypt_data'] 41 | return encrypted_data 42 | 43 | 44 | def get_decrypted_data(encrypted_data): 45 | with open('qimingpian_decrypt.js', 'r', encoding='utf-8') as f: 46 | qimingpian_js = f.read() 47 | decrypted_data = execjs.compile(qimingpian_js).call('getDecryptedData', encrypted_data) 48 | return json.loads(decrypted_data) 49 | 50 | 51 | def main(): 52 | encrypted_data = get_encrypted_data() 53 | decrypted_data = get_decrypted_data(encrypted_data) 54 | print(decrypted_data) 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /JSReverse/www_xinshangmeng_com/README.md: -------------------------------------------------------------------------------- 1 | ## XX新商盟 2 | 3 | 应版权方要求,已删除本项目 4 | 5 | ![](https://s2.loli.net/2022/07/22/pj12vM9Zg3QyHJh.png) 6 | 7 | -------------------------------------------------------------------------------- /JSReverse/xueqiu_com/get_acw_sc_v2.js: -------------------------------------------------------------------------------- 1 | /* # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-12-29 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: get_acw_sc_v2.js 8 | # @Software: PyCharm 9 | # ================================== */ 10 | 11 | 12 | var _0x5e8b26 = '3000176000856006061501533003690027800375' 13 | 14 | var getAcwScV2 = function (arg1) { 15 | String['prototype']['hexXor'] = function (_0x4e08d8) { 16 | var _0x5a5d3b = ''; 17 | for (var _0xe89588 = 0x0; _0xe89588 < this['length'] && _0xe89588 < _0x4e08d8['length']; _0xe89588 += 0x2) { 18 | var _0x401af1 = parseInt(this['slice'](_0xe89588, _0xe89588 + 0x2), 0x10); 19 | var _0x105f59 = parseInt(_0x4e08d8['slice'](_0xe89588, _0xe89588 + 0x2), 0x10); 20 | var _0x189e2c = (_0x401af1 ^ _0x105f59)['toString'](0x10); 21 | if (_0x189e2c['length'] == 0x1) { 22 | _0x189e2c = '0' + _0x189e2c; 23 | } 24 | _0x5a5d3b += _0x189e2c; 25 | } 26 | return _0x5a5d3b; 27 | }; 28 | String['prototype']['unsbox'] = function () { 29 | var _0x4b082b = [0xf, 0x23, 0x1d, 0x18, 0x21, 0x10, 0x1, 0x26, 0xa, 0x9, 0x13, 0x1f, 0x28, 0x1b, 0x16, 0x17, 0x19, 0xd, 0x6, 0xb, 0x27, 0x12, 0x14, 0x8, 0xe, 0x15, 0x20, 0x1a, 0x2, 0x1e, 0x7, 0x4, 0x11, 0x5, 0x3, 0x1c, 0x22, 0x25, 0xc, 0x24]; 30 | var _0x4da0dc = []; 31 | var _0x12605e = ''; 32 | for (var _0x20a7bf = 0x0; _0x20a7bf < this['length']; _0x20a7bf++) { 33 | var _0x385ee3 = this[_0x20a7bf]; 34 | for (var _0x217721 = 0x0; _0x217721 < _0x4b082b['length']; _0x217721++) { 35 | if (_0x4b082b[_0x217721] == _0x20a7bf + 0x1) { 36 | _0x4da0dc[_0x217721] = _0x385ee3; 37 | } 38 | } 39 | } 40 | _0x12605e = _0x4da0dc['join'](''); 41 | return _0x12605e; 42 | }; 43 | var _0x23a392 = arg1['unsbox'](); 44 | arg2 = _0x23a392['hexXor'](_0x5e8b26); 45 | return arg2 46 | }; 47 | 48 | // 测试输出 49 | // var arg1 = '2410463826D86A52A5BB43A13A80BAE6C4122A73'; 50 | // console.log(getAcwScV2(arg1)) 51 | -------------------------------------------------------------------------------- /JSReverse/xueqiu_com/main.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-12-29 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: main.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import re 13 | import execjs 14 | import requests 15 | 16 | 17 | index_url = "https://xueqiu.com/today" 18 | news_test_url = "https://xueqiu.com/statuses/hot/listV2.json?since_id=-1&max_id=294528&size=15" 19 | headers = { 20 | "Host": "xueqiu.com", 21 | "Referer": "https://xueqiu.com/today", 22 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36", 23 | } 24 | 25 | 26 | def get_complete_cookie(): 27 | complete_cookie = {} 28 | # 第一次不带参数访问首页,获取 acw_tc 和 acw_sc__v2 29 | response = requests.get(url=index_url, headers=headers) 30 | complete_cookie.update(response.cookies.get_dict()) 31 | arg1 = re.findall("arg1='(.*?)'", response.text)[0] 32 | with open('get_acw_sc_v2.js', 'r', encoding='utf-8') as f: 33 | acw_sc_v2_js = f.read() 34 | acw_sc__v2 = execjs.compile(acw_sc_v2_js).call('getAcwScV2', arg1) 35 | complete_cookie.update({"acw_sc__v2": acw_sc__v2}) 36 | # 第二次访问首页,获取其他 cookies 37 | response2 = requests.get(url=index_url, headers=headers, cookies=complete_cookie) 38 | complete_cookie.update(response2.cookies.get_dict()) 39 | return complete_cookie 40 | 41 | 42 | def news_test(cookies): 43 | response = requests.get(url=news_test_url, headers=headers, cookies=cookies) 44 | print(response.json()) 45 | 46 | 47 | if __name__ == '__main__': 48 | complete_cookie = get_complete_cookie() 49 | news_test(complete_cookie) 50 | -------------------------------------------------------------------------------- /JSReverse/zwfw_san-he_gov_cn/zwfw_san_he.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-08-02 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: zwfw_san_he.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import re 13 | 14 | import execjs 15 | import requests 16 | 17 | 18 | index_url = 'http://zwfw.san-he.gov.cn/icity/icity/guestbook/interact' 19 | data_url = 'http://zwfw.san-he.gov.cn/icity/api-v2/app.icity.guestbook.WriteCmd/getList' 20 | headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'} 21 | session = requests.session() 22 | 23 | 24 | def get_encrypted_parameters(signature): 25 | with open('zwfw_san_he_encrypt.js', 'r', encoding='utf-8') as f: 26 | zwfw_san_he_js = f.read() 27 | encrypted_parameters = execjs.compile(zwfw_san_he_js).call('getDecryptedParameters', signature) 28 | return encrypted_parameters 29 | 30 | 31 | def get_signature_and_cookies(): 32 | response = session.get(url=index_url, headers=headers) 33 | cookies = response.cookies.get_dict() 34 | cookie = cookies['ICITYSession'] 35 | signature = re.findall(r'signature = "(.*)"', response.text)[0] 36 | return cookie, signature 37 | 38 | 39 | def get_data(cookie, parameters, page): 40 | payload_data = {'start': page*7, 'limit': 7, 'TYPE@=': '2', 'OPEN@=': '1'} 41 | params = {'s': parameters['s'], 't': parameters['t']} 42 | cookies = {'ICITYSession': cookie} 43 | response = session.post(url=data_url, headers=headers, json=payload_data, params=params, cookies=cookies).json() 44 | print(payload_data, response) 45 | 46 | 47 | def main(): 48 | ck, sig = get_signature_and_cookies() 49 | for page in range(10): 50 | # 采集10页数据 51 | param = get_encrypted_parameters(sig) 52 | get_data(ck, param, page) 53 | 54 | 55 | if __name__ == '__main__': 56 | main() 57 | -------------------------------------------------------------------------------- /JSReverse/zwfw_san-he_gov_cn/zwfw_san_he_encrypt.js: -------------------------------------------------------------------------------- 1 | isNotNull = function (obj) { 2 | if (obj === undefined || obj === null || obj == "null" || obj === "" || obj == "undefined") 3 | return false; 4 | return true; 5 | }; 6 | 7 | function getDecryptedParameters(__signature) { 8 | var sig = ""; 9 | var chars = "0123456789abcdef"; 10 | if (!isNotNull(__signature)) { 11 | var curTime = parseInt(Math.random() * (9999 - 1000 + 1) + 1000) + "" + Date.parse(new Date()); 12 | sig = chars.charAt(parseInt(Math.random() * (15 - 15 + 1) + 10)) + chars.charAt(curTime.length) + "" + curTime; 13 | } else { 14 | sig = __signature; 15 | } 16 | 17 | var key = ""; 18 | var keyIndex = -1; 19 | for (var i = 0; i < 6; i++) { 20 | var c = sig.charAt(keyIndex + 1); 21 | key += c; 22 | keyIndex = chars.indexOf(c); 23 | if (keyIndex < 0 || keyIndex >= sig.length) { 24 | keyIndex = i; 25 | } 26 | } 27 | 28 | var timestamp = parseInt(Math.random() * (9999 - 1000 + 1) + 1000) + "_" + key + "_" + Date.parse(new Date()); 29 | var t = timestamp; 30 | //LEx.azdg.encrypt(timestamp,key); 31 | t = t.replace(/\+/g, "_"); 32 | return {"s": sig, "t": t}; 33 | } 34 | 35 | // 测试样例 36 | // console.log(getDecryptedParameters("c988121626057020055")) 37 | -------------------------------------------------------------------------------- /Material/手机UA,累计18428条.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/Material/手机UA,累计18428条.txt -------------------------------------------------------------------------------- /SignIn/csdn-sign-in/CSDN_1.py: -------------------------------------------------------------------------------- 1 | # ==================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2021-05-29 4 | # @Author : TRHX • 鲍勃 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: CSDN.py 8 | # @Software: PyCharm 9 | # ==================================== 10 | 11 | 12 | import requests 13 | import json 14 | 15 | 16 | CSDN_ID = '' # 你的 CSDN ID 17 | COOKIE = '' # 你的 cookie 18 | IF_LUCK_DRAW = True # 是否开启抽奖 19 | 20 | 21 | class CSDN: 22 | def __init__(self) -> None: 23 | self.UUID = COOKIE.split(';', 1)[0].split('=', 1)[1] 24 | self.USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36' 25 | self.SIGN_IN_URL = 'https://me.csdn.net/api/LuckyDraw_v2/signIn' 26 | self.LUCKY_DRAW_URL = 'https://me.csdn.net/api/LuckyDraw_v2/goodLuck' 27 | self.DRAW_TIMES = 0 # 可抽奖次数 28 | self.HEADERS = { 29 | 'accept': 'application/json, text/plain, */*', 30 | 'accept-encoding': 'gzip, deflate, br', 31 | 'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', 32 | 'content-length': '243', 33 | 'content-type': 'application/json;charset=UTF-8', 34 | 'cookie': COOKIE, 35 | 'origin': 'https://i.csdn.net', 36 | 'referer': 'https://i.csdn.net/', 37 | 'sec-fetch-dest': 'empty', 38 | 'sec-fetch-mode': 'cors', 39 | 'sec-fetch-site': 'same-site', 40 | 'user-agent': self.USER_AGENT 41 | } 42 | self.DATA = { 43 | 'ip': '', 44 | 'platform': 'pc-my', 45 | 'product': 'pc', 46 | 'user_agent': self.USER_AGENT, 47 | 'username': CSDN_ID, 48 | 'uuid': self.UUID 49 | } 50 | 51 | def csdn_sign_in(self) -> None: 52 | response = requests.post(url=self.SIGN_IN_URL, headers=self.HEADERS, data=self.DATA) 53 | result = json.loads(response.text) 54 | # print(result) 55 | 56 | if result['code'] == 200: 57 | if not result['data']['isSigned'] and result['data']['signed']: 58 | keep_count = result['data']['keepCount'] 59 | total_count = result['data']['totalCount'] 60 | total_signed_count = result['data']['totalSignedCount'] 61 | # self.STAR = result['data']['star'] 62 | self.DRAW_TIMES = result['data']['drawTimes'] 63 | print('签到成功!你已连续签到 {} 天,累计签到 {} 天,当前已有 {} 人签到。'.format(keep_count, total_count, total_signed_count)) 64 | elif result['data']['isSigned']: 65 | print('你今天已经签到过了哟!') 66 | else: 67 | print('签到失败!') 68 | elif result['code'] == 400102: 69 | print('签到失败!{} 用户不存在或者 cookie 错误!请检查 CSDN ID 或尝试重置 cookie!'.format(CSDN_ID)) 70 | else: 71 | print('签到失败!') 72 | 73 | def csdn_luck_draw(self) -> None: 74 | if self.DRAW_TIMES != 0: 75 | response = requests.post(url=self.LUCKY_DRAW_URL, headers=self.HEADERS, data=self.DATA) 76 | result = json.loads(response.text) 77 | # print(result) 78 | 79 | if result['code'] == 200: 80 | if result['data']['can_draw']: 81 | prize_title = result['data']['prize_title'] 82 | print('抽奖成功!恭喜你获得{}'.format(prize_title)) 83 | elif not result['data']['can_draw']: 84 | print('抽奖机会已经用完了哟!') 85 | else: 86 | print('抽奖失败!') 87 | elif result['code'] == 400102: 88 | print('抽奖失败!{} 用户不存在或者 cookie 错误!请检查 CSDN ID 或尝试重置 cookie!'.format(CSDN_ID)) 89 | else: 90 | print('抽奖失败!') 91 | 92 | 93 | def run() -> None: 94 | c = CSDN() 95 | c.csdn_sign_in() 96 | if IF_LUCK_DRAW: 97 | c.csdn_luck_draw() 98 | 99 | 100 | if __name__ == '__main__': 101 | run() 102 | -------------------------------------------------------------------------------- /SignIn/csdn-sign-in/README.md: -------------------------------------------------------------------------------- 1 | ## CSDN 自动签到抽奖 2 | 3 | 实现时间:2021-05-29 4 | 5 | CSDN 文章:https://itrhx.blog.csdn.net/article/details/117375471 6 | 7 | 注意事项: 8 | 9 | - cookie 的值需要你登录后 F12 查看复制过来,~~cookie 的有效期是多久暂时不得而知,等下次失效了我再回来告诉你们有效期是多久,如果我没说,那就代表一直没失效!😁~~ 10 | 11 | - 经过测试,cookie 的有效期在 45 天左右,失效后需要重新复制一个新 cookie 过来! 12 | 13 | - 如果你开启了自动抽奖,程序会识别你当前还有多少次抽奖次数,如果抽奖次数为0,则仍然不执行抽奖任务! 14 | 15 | # CSDN_1.py 16 | 17 | 简单的签到抽奖功能,运行前把 CSDN_ID 和 COOKIE 设置成你的即可。 18 | 19 | # CSDN_2.py 20 | 21 | 通过 GitHub Actions 实现了每天自动签到抽奖功能,签到结果可选通知:Server 酱、企业微信、钉钉,代码不能直接运行,这是放到 GitHub Actions 上执行的代码,使用方法见 https://github.com/TRHX/CSDNSignIn ,如果要本地运行,则需要将配置项目 1 2 3 中的 os.environ["xxxxx"] 换成各自对应的值! 22 | -------------------------------------------------------------------------------- /SpiderDataVisualization/51job/README.md: -------------------------------------------------------------------------------- 1 | # 前程无忧招聘信息爬取 + 数据可视化 2 | 3 | **2020年10月测试,增加了反爬,此代码已失效!!!** 4 | 5 | - 爬取时间:2020-07-11 6 | 7 | - 实现目标:根据用户输入的关键字爬取相关职位信息存入 MongoDB,读取数据进行可视化展示。 8 | 9 | - 涉及知识:请求库 requests、Xpath 语法、数据库 MongoDB、数据处理 Numpy、Pandas、数据可视化 Matplotlib。 10 | 11 | - CSDN 链接:https://itrhx.blog.csdn.net/article/details/107315136 12 | 13 | - 个人博客链接:https://www.itrhx.com/2020/07/13/A90-pyspider-51job/ 14 | 15 | - MongoDB 数据截图: 16 | 17 | ![06](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A90/06.png) 18 | 19 | - CSV 文件截图: 20 | 21 | ![07](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A90/07.png) 22 | 23 | - JSON 文件截图: 24 | 25 | ![08](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A90/08.png) 26 | 27 | - 关系图: 28 | 29 | ![09](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A90/09.png) 30 | 31 | ![10](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A90/10.png) 32 | -------------------------------------------------------------------------------- /SpiderDataVisualization/51job/draw_bar_chart.py: -------------------------------------------------------------------------------- 1 | # ================================== 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2020-07-11 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: draw_bar_chart.py 8 | # @Software: PyCharm 9 | # ================================== 10 | 11 | 12 | import pymongo 13 | import numpy as np 14 | import pandas as pd 15 | import matplotlib.pyplot as plt 16 | 17 | 18 | def processing_data(): 19 | # 连接数据库,从数据库读取数据(也可以导出后从文件中读取) 20 | client = pymongo.MongoClient(host='localhost', port=27017) 21 | db = client.job51_spider 22 | collection = db.data 23 | 24 | # 读取数据并转换为 DataFrame 对象 25 | data = pd.DataFrame(list(collection.find())) 26 | data = data[['工资', '经验', '学历']] 27 | 28 | # 使用正则表达式选择空白的字段并填充为缺失值,然后删除带有缺失值的所有行 29 | data.replace(to_replace=r'^\s*$', value=np.nan, regex=True, inplace=True) 30 | data = data.dropna() 31 | 32 | # 对工资数据进行清洗,处理后的工作单位:元/月 33 | data['工资'] = data['工资'].apply(wish_data) 34 | return data 35 | 36 | 37 | def wish_data(wages_old): 38 | 39 | """ 40 | 数据清洗规则: 41 | 分为元/天,千(以上/下)/月,万(以上/下)/月,万(以上/下)/年 42 | 若数据是一个区间的,则求其平均值,最后的值统一单位为元/月 43 | """ 44 | 45 | if '元/天' in wages_old: 46 | if '-' in wages_old.split('元')[0]: 47 | wages1 = wages_old.split('元')[0].split('-')[0] 48 | wages2 = wages_old.split('元')[0].split('-')[1] 49 | wages_new = (float(wages2) + float(wages1)) / 2 * 30 50 | else: 51 | wages_new = float(wages_old.split('元')[0]) * 30 52 | return wages_new 53 | 54 | elif '千/月' in wages_old or '千以下/月' in wages_old or '千以上/月' in wages_old: 55 | if '-' in wages_old.split('千')[0]: 56 | wages1 = wages_old.split('千')[0].split('-')[0] 57 | wages2 = wages_old.split('千')[0].split('-')[1] 58 | wages_new = (float(wages2) + float(wages1)) / 2 * 1000 59 | else: 60 | wages_new = float(wages_old.split('千')[0]) * 1000 61 | return wages_new 62 | 63 | elif '万/月' in wages_old or '万以下/月' in wages_old or '万以上/月' in wages_old: 64 | if '-' in wages_old.split('万')[0]: 65 | wages1 = wages_old.split('万')[0].split('-')[0] 66 | wages2 = wages_old.split('万')[0].split('-')[1] 67 | wages_new = (float(wages2) + float(wages1)) / 2 * 10000 68 | else: 69 | wages_new = float(wages_old.split('万')[0]) * 10000 70 | return wages_new 71 | 72 | elif '万/年' in wages_old or '万以下/年' in wages_old or '万以上/年' in wages_old: 73 | if '-' in wages_old.split('万')[0]: 74 | wages1 = wages_old.split('万')[0].split('-')[0] 75 | wages2 = wages_old.split('万')[0].split('-')[1] 76 | wages_new = (float(wages2) + float(wages1)) / 2 * 10000 / 12 77 | else: 78 | wages_new = float(wages_old.split('万')[0]) * 10000 / 12 79 | return wages_new 80 | 81 | 82 | def wages_experience_chart(data): 83 | # 根据经验分类,求不同经验对应的平均薪资 84 | wages_experience = data.groupby('经验').mean() 85 | 86 | # 获取经验和薪资的值,将其作为画图的 x 和 y 数据 87 | w = wages_experience['工资'].index.values 88 | e = wages_experience['工资'].values 89 | 90 | # 按照经验对数据重新进行排序,薪资转为 int 类型(也可以直接在前面对 DataFrame 按照薪资大小排序) 91 | wages = [w[6], w[1], w[2], w[3], w[4], w[5], w[0]] 92 | experience = [int(e[6]), int(e[1]), int(e[2]), int(e[3]), int(e[4]), int(e[5]), int(e[0])] 93 | 94 | # 绘制柱状图 95 | plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] 96 | plt.figure(figsize=(9, 6)) 97 | x = wages 98 | y = experience 99 | color = ['#E41A1C', '#377EB8', '#4DAF4A', '#984EA3', '#FF7F00', '#FFFF33', '#A65628'] 100 | plt.bar(x, y, color=color) 101 | for a, b in zip(x, y): 102 | plt.text(a, b, b, ha='center', va='bottom') 103 | plt.title('Python 相关职位经验与平均薪资关系', fontsize=13) 104 | plt.xlabel('经验', fontsize=13) 105 | plt.ylabel('平均薪资(元 / 月)', fontsize=13) 106 | plt.savefig('wages_experience_chart.png') 107 | plt.show() 108 | 109 | 110 | def wages_education_chart(data): 111 | # 根据学历分类,求不同学历对应的平均薪资 112 | wages_education = data.groupby('学历').mean() 113 | 114 | # 获取学历和薪资的值,将其作为画图的 x 和 y 数据 115 | wages = wages_education['工资'].index.values 116 | education = [int(i) for i in wages_education['工资'].values] 117 | 118 | # 绘制柱状图 119 | plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] 120 | plt.figure(figsize=(9, 6)) 121 | x = wages 122 | y = education 123 | color = ['#E41A1C', '#377EB8', '#4DAF4A'] 124 | plt.bar(x, y, color=color) 125 | for a, b in zip(x, y): 126 | plt.text(a, b, b, ha='center', va='bottom') 127 | plt.title('Python 相关职位学历与平均薪资关系', fontsize=13) 128 | plt.xlabel('学历', fontsize=13) 129 | plt.ylabel('平均薪资(元 / 月)', fontsize=13) 130 | plt.savefig('wages_education_chart.png') 131 | plt.show() 132 | 133 | 134 | if __name__ == '__main__': 135 | 136 | """ 137 | processing_data: 数据处理 138 | wages_experience_bar: 平均薪资与经验关系柱状图 139 | wages_education_bar: 平均薪资与学历关系柱状图 140 | """ 141 | 142 | job_data = processing_data() 143 | wages_experience_chart(job_data) 144 | wages_education_chart(job_data) 145 | -------------------------------------------------------------------------------- /SpiderDataVisualization/51job/wages_education_chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/SpiderDataVisualization/51job/wages_education_chart.png -------------------------------------------------------------------------------- /SpiderDataVisualization/51job/wages_experience_chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/SpiderDataVisualization/51job/wages_experience_chart.png -------------------------------------------------------------------------------- /SpiderDataVisualization/COVID-19/COVID-19-China.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/SpiderDataVisualization/COVID-19/COVID-19-China.xlsx -------------------------------------------------------------------------------- /SpiderDataVisualization/COVID-19/COVID-19-Global.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/SpiderDataVisualization/COVID-19/COVID-19-Global.xlsx -------------------------------------------------------------------------------- /SpiderDataVisualization/COVID-19/README.md: -------------------------------------------------------------------------------- 1 | - ## COVID-19 肺炎疫情数据实时监控 2 | 3 | - 预览地址:[http://cov.itrhx.com/](http://cov.itrhx.com/) 4 | 5 | - 数据来源:[https://voice.baidu.com/act/newpneumonia/newpneumonia/](https://voice.baidu.com/act/newpneumonia/newpneumonia/) 6 | 7 | - pyecharts 文档:[https://pyecharts.org/](https://pyecharts.org/) 8 | 9 | - openpyxl 文档:[https://openpyxl.readthedocs.io/](https://openpyxl.readthedocs.io/) 10 | 11 | - wordcloud 文档:[http://amueller.github.io/word_cloud/](http://amueller.github.io/word_cloud/) 12 | 13 | - CSDN 链接:https://itrhx.blog.csdn.net/article/details/107140534 14 | 15 | - 个人博客链接:https://www.itrhx.com/2020/07/06/A89-COVID-19/ 16 | 17 | - 思维导图 / Excel 数据 / 词云图 / pyecharts 地图截图: 18 | 19 | ![01](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A89/01.png) 20 | 21 | ![03](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A89/03.png) 22 | 23 | ![04](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A89/04.png) 24 | 25 | ![05](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A89/05.png) 26 | 27 | ![06](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A89/06.png) 28 | 29 | ![07](https://cdn.jsdelivr.net/gh/TRHX/ImageHosting/ITRHX-PIC/A89/07.png) 30 | -------------------------------------------------------------------------------- /SpiderDataVisualization/COVID-19/WordCloud-China.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/SpiderDataVisualization/COVID-19/WordCloud-China.png -------------------------------------------------------------------------------- /SpiderDataVisualization/COVID-19/WordCloud-Global.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/SpiderDataVisualization/COVID-19/WordCloud-Global.png -------------------------------------------------------------------------------- /SpiderDataVisualization/COVID-19/data_wordcloud.py: -------------------------------------------------------------------------------- 1 | # ============================================= 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2020-07-06 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: data_wordcloud.py 8 | # @Software: PyCharm 9 | # ============================================= 10 | 11 | import openpyxl 12 | import wordcloud 13 | 14 | 15 | def china_wordcloud(): 16 | wb = openpyxl.load_workbook('COVID-19-China.xlsx') # 获取已有的xlsx文件 17 | ws_china = wb['中国省份疫情数据'] # 获取中国省份疫情数据表 18 | ws_china.delete_rows(1) # 删除第一行 19 | china_dict = {} # 将省份及其累计确诊按照键值对形式储存在字典中 20 | for data in ws_china.values: 21 | china_dict[data[0]] = int(data[2]) 22 | word_cloud = wordcloud.WordCloud(font_path='C:/Windows/Fonts/simsun.ttc', 23 | background_color='#CDC9C9', 24 | min_font_size=15, 25 | width=900, height=500) 26 | word_cloud.generate_from_frequencies(china_dict) 27 | word_cloud.to_file('WordCloud-China.png') 28 | print('中国省份疫情词云图绘制完毕!') 29 | 30 | 31 | def global_wordcloud(): 32 | wb = openpyxl.load_workbook('COVID-19-Global.xlsx') 33 | ws_global = wb['全球各国疫情数据'] 34 | ws_global.delete_rows(1) 35 | global_dict = {} 36 | for data in ws_global.values: 37 | global_dict[data[0]] = int(data[2]) 38 | word_cloud = wordcloud.WordCloud(font_path='C:/Windows/Fonts/simsun.ttc', 39 | background_color='#CDC9C9', 40 | width=900, height=500) 41 | word_cloud.generate_from_frequencies(global_dict) 42 | word_cloud.to_file('WordCloud-Global.png') 43 | print('全球各国疫情词云图绘制完毕!') 44 | 45 | 46 | if __name__ == '__main__': 47 | 48 | """ 49 | china_wordcloud: 中国累计确诊词云图 50 | global_wordcloud: 全球累计确诊词云图 51 | """ 52 | 53 | china_wordcloud() 54 | global_wordcloud() 55 | -------------------------------------------------------------------------------- /SpiderDataVisualization/COVID-19/main.py: -------------------------------------------------------------------------------- 1 | # ============================================= 2 | # --*-- coding: utf-8 --*-- 3 | # @Time : 2020-07-06 4 | # @Author : TRHX 5 | # @Blog : www.itrhx.com 6 | # @CSDN : itrhx.blog.csdn.net 7 | # @FileName: main.py 8 | # @Software: PyCharm 9 | # ============================================= 10 | 11 | import data_get 12 | import data_wordcloud 13 | import data_map 14 | 15 | 16 | data_dict = data_get.init() 17 | data_get.china_total_data(data_dict) 18 | data_get.global_total_data(data_dict) 19 | data_get.china_daily_data(data_dict) 20 | data_get.foreign_daily_data(data_dict) 21 | 22 | data_wordcloud.china_wordcloud() 23 | data_wordcloud.global_wordcloud() 24 | 25 | data_map.all_map() 26 | -------------------------------------------------------------------------------- /image/chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/image/chat.png -------------------------------------------------------------------------------- /image/spider_skill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TRHX/Python3-Spider-Practice/34acfc2fa234db3211ef0033f5e7c9573713687f/image/spider_skill.png --------------------------------------------------------------------------------