├── 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 | 
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 | 
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 | 
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 | 
20 |
21 | 
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 | 
21 |
22 | 储存到 MongoDB 的数据:
23 | 
24 |
25 | 数据导出为 CSV 文件:
26 | 
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 | 
--------------------------------------------------------------------------------
/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 | 
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 | 
18 |
19 | 
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 | 
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 | 
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 | 
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 | 
18 |
19 | - CSV 文件截图:
20 |
21 | 
22 |
23 | - JSON 文件截图:
24 |
25 | 
26 |
27 | - 关系图:
28 |
29 | 
30 |
31 | 
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 | 
20 |
21 | 
22 |
23 | 
24 |
25 | 
26 |
27 | 
28 |
29 | 
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
--------------------------------------------------------------------------------