前端时间我的一个同事给我看了一个软件,提供京东账号,设置一定的条件后,就可以自动申请京东试用的产品,可是他担心提供账号密码不安全,刚好我也在学习Python中,就当做一个训练。
0.需要使用到的库
import requests # 网络请求库
from bs4 import BeautifulSoup # HTML字符串解析库
import json # Json转换库
import random # 随机数
import time # 时间库
import cookielib # 处理网络请求Cookie的库
1.登录
1-1.获取验证码
这里我是通过请求 京东登录页面,从html中获取到下载验证码图片的URL,并将验证码图片保存到本地以供查看。
def get_auth_img(self, url):
auth_code_url = 'http:' + url
auth_img = s.get(auth_code_url, headers=self.headers)
with open(sys.path[0] + '/auth.jpg', 'wb') as f:
f.write(auth_img.content)
code = input('请输入验证码(例:\'xxxx\'):') # input函数将会在打印台接收一个输入
return code
1-2.登录
登录使用的是 京东登录接口,登录成功后需要使用 cookielib 库将Cookie存下来以供后面所有接口调用。
def login(self):
url = 'https://passport.jd.com/uc/loginService'
data = self.get_login_data()
headers = {
'Referer': 'https://passport.jd.com/uc/login?ltype=logout',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0',
'X-Requested-With': 'XMLHttpRequest'
}
global cookieJar
# 初始化一个CookieJar来处理Cookie
cookieJar = cookielib.CookieJar()
login_re = s.post(url, data=data, headers=headers)
cookieJar = login_re.cookies
content = login_re.text
result = json.loads(content[1: -1])
return result
2.获取元数据
2-1.获取京东试用列表
获取列表是直接使用的是 列表的获取链接, 通过HTML里面的items获取到商品信息,放在数组中等待筛选
def get_page_html(self, page):
try:
url = "https://try.jd.com/activity/getActivityList?page=" + str(page)
res = requests.get(url, headers=self.headers)
html_str = res.text
return html_str
except Exception as e:
print("获取使用列表页面:%s"% e)
根据获取到HTML字符串筛选出每一个item,转成对象,存储在数组中
besoup = BeautifulSoup(html_str, features='lxml')
div_str = besoup.find_all('div', attrs={'class': "con"})
items = BeautifulSoup(str(div_str))
uls = items.find_all('li')
# 加入数组/其他操作
2-2.获取商品价格
根据获取到的skuId请求 价格获取接口获取当前商品价格,当skuIds=xxx,xxx,xxx,xxx时,会返回一个对象数组,返回这些id对应商品的价格
def get_sp_prices(self, sku_ids):
try:
url = "https://p.3.cn/prices/mgets?skuIds=" + str(sku_ids) +"&origin=2"
res = requests.get(url, headers=self.headers, cookies=cookieJar)
jsStr = res.content
jsonArr = json.loads(jsStr)
return jsonArr
except Exception as e:
print("获取商品价格数组:%s"% e)
2-3.判断是否已经申请过该商品
通过请求 判断申请过与否接口来获取已经申请过的商品,同上当activityIds=xxx,xxx,xxx会返回字典对象数组
def appled_sp_ids(self, ac_ids):
global cookieJar
try:
url = "https://try.jd.com/user/getApplyStateByActivityIds?activityIds=" + str(ac_ids)
res = requests.post(url, headers=self.headers, cookies=cookieJar)
jsStr = res.content
jsonArr = json.loads(jsStr)
appled_sp_ids = ''
for dic in jsonArr:
appled_sp_ids = appled_sp_ids + "," + str(dic['activityId'])
# 每一个dic的数据{u'activityId': 313130, u'selected': 10}
appled_sp_ids = appled_sp_ids[1:]
return appled_sp_ids
except Exception as e:
print("获取已经申请过的id接口:%s"% e)
2-4.过滤关键词
通过比较从配置文件获取的用,隔开的关键词和视频名称对比过滤掉包含关键词的商品
def have_key_word(self, sp_title):
if self.keyWord is '':
return False
keyArr = self.keyWord.split(',')
have = False
for key in keyArr:
if key in sp_title:
have = True
return have
return have
2-5.筛选出符合条件的商品
通过本地配置的JSON文件获取到的属性筛选商品数组
for index, child in enumerate(self.canApplyArr):
soup = BeautifulSoup(str(child))
sp_activity_id = child.attrs['activity_id']
# sku_id = child.attrs['sku_id'] # 获取商品编号
sp_name = soup.find('div', attrs={'class': "p-name"})
# 无法再列表页获取价格,获取出来都是:暂无报价,所以跳转到详情页获取
# price = self.goto_sp_price(sku_id)
# 判断是否已申请
if (sp_activity_id not in appled_ids) or (appled_ids is ''):
# 随机等待秒数
sleep_s = random.randint(self.minSecond, self.maxSecond)
print("待申请ID为:%s" % sp_activity_id)
print("申请中,等待%s " % sleep_s)
# 进行申请
time.sleep(sleep_s)
apply_dic = self.apply_sp(sp_activity_id)
# 后继处理
2-5.申请商品
通过调用 商品申请接口 来申请商品
def apply_sp(self, sp_id):
global cookieJar
try:
url = "https://try.jd.com/migrate/apply?activityId=" + str(sp_id) + "&source=0"
res = requests.post(url, headers=self.headers, cookies=cookieJar)
html_str = res.text
print(html_str)
dic = json.loads(str(html_str))
return dic
except Exception as e:
print("申请试用页面:%s"% e)
3.调用
通过预先配置好的JSON文件获取需要的参数,依次为:京东用户名、密码、最小/大时间、去除关键词、最低价格
# 从JD_Configer.json文件中读取配置
jd_configer = open("JD_Configer.json")
setting = json.load(jd_configer, encoding="utf-8")
user_name = setting["name"]
user_password = setting["password"]
minS = setting["minTime"]
maxS = setting["maxTime"]
minP = setting["minPrice"]
keyW = setting["keyWord"]
jd_test = JDTestUse(user_name, user_password, minS, maxS, minP, keyW)
result = jd_test.login()
jd_test.get_ten_page_of_once(jd_test.page)
小弟Python初学者,如有错误,请大佬指出,谢谢!