天猫自动进入商品页下单商品
- 步骤
- 关键部分
- 多线程登录
- 求两个时间的时间差
- 没有找到网页元素的原因
- 向下滑动页面
- 进入购买界面,点击“立即购买”
- 表格类
- 需要继续改进的地方
步骤
- 图形化界面
- 采用读取表格来登录账号,多线程
- 直接进入商品页进行购买
- 提交订单
关键部分
多线程登录
要实现多个账号同时登录,考虑使用多线程,简单的多线程就可以了。
threads = []
for i in range(0,60):
t = threading.Thread(target=function_a, args=( ))
threads.append(t)
t.start()
for t in threads:
t.join()
(这也太基础教程了8)
提起Python多线程不得不提的GILpython多线程join()方法 python 默认参数创建线程后,不管主线程是否执行完毕,都会等待子线程执行完毕才一起退出,join方法的作用是阻塞,等待子线程结束,join方法有一个参数是timeout,即如果主线程等待timeout,子线程还没有结束,则主线程强制结束子线程。
求两个时间的时间差
输入时间为进行抢购的时间,计算出当前时间与预定时间的差值,然后…sleep相应的时间,就可以进行抢购了。
from dateutil.parser import parse
a = parse('2017-10-01/12:12:12')
b = parse('2013-3-4/10:10:10')
(a-b).days
(a-b).seconds
(a-b).total_seconds()
- days:来获取时间差的天数
- seconds:来获取时间差中的秒数。注意,seconds获得的秒只是时间差中的小时、分钟和秒部分的和,并没有包含时间差的天数
- total_seconds:来获取准确的时间差,并将时间差转换为秒,如果相差的有天数,就用这个方法计算才准确
dateutil.parser就是与日期相关库里的一个日期解析器,将字符串转换为日期格式
In: parser.parse(‘2020-06-01’)
Out[131]: datetime.datetime(2020, 6, 1,0, 0)
In: parser.parse(‘2020-06-01 12:20:40’)
Out[131]: datetime.datetime(2020, 6, 1,12, 20,40)
没有找到网页元素的原因
转载自:Selenium笔记(7)常见的坑,补充成下:
- 分辨率原因
- 需要滚动页面
- 其他元素遮挡
- 可以换一种方式描述位置,比如id,xpath…
- 动态id定位不到元素
- 点击速度过快,页面没有加载出来,只需要进行合理等待时间
向下滑动页面
selenium本身不提供滑动的方法,用JS滚动页面
def swipe_down(self,second):
for i in range(int(second / 0.1)):
js = "var q=document.documentElement.scrollTop=" + str(300 + 200 * i)
self.browser.execute_script(js)
要获取当前页面的滚动条纵坐标位置,用:document.documentElement.scrollTop;
而不是:document.body.scrollTop;
因为documentElement 对应的是 html 标签,而 body 对应的是 body 标签。
进入购买界面,点击“立即购买”
def get_shop(self,shop_url,buy_time):
print("正在打开需要抢购的页面")
self.browser.get(shop_url)
while True:
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
if buy_time > now:
sleep(self.get_time_seconds(now,buy_time))
try:
self.swipe_down()
#等待购买按钮出现
link_buy = self.wait.until(EC.visibility_of_element_located((By.XPATH, '//div[@class="tb-btn-buy"]/a')))
link_buy.click()
sut_j = self.wait.until(EC.visibility_of_element_located((By.XPATH, '//div[@class="wrapper"]/a')))
sut_j.click()
print(f"抢购成功,请尽快付款")
sleep(3)
break
except:
self.browser.refresh() # 刷新页面
link_buy = self.wait.until(EC.presence_of_element_located((By.ID, 'J_LinkBuy')))
link_buy.click()
sut_j = self.wait.until(EC.presence_of_element_located((By.XPATH, '//div[@class="wrapper"]/a')))
sut_j.click()
print(f"抢购成功,请尽快付款")
sleep(3)
break
参数:shop_url是要购买的商品链接,buy_time是抢购的时间
查看网页源代码,前段时间用id定位购买按钮,是可行的,这两天突然定位不到了不知道为什么,所以换了一种方式,用xpath定位的相对路径方法查找到该元素。
找到元素之后click就可以了。
表格类
class ExcelUtil:
def __init__(self, excel_path, sheet_name):
self.data = xlrd.open_workbook(excel_path)
self.table = self.data.sheet_by_name(sheet_name)
# 获取第一行作为key值
self.keys = self.table.row_values(0)
# 获取总行数
self.rowNum = self.table.nrows
# 获取总列数
self.colNum = self.table.ncols
def dict_data(self):
if self.rowNum <= 1:
print("总行数小于1")
else:
r = [] # 存放读取数据
j = 1
for i in range(self.rowNum - 1):
s = {} # 存放每一行的键值对
# 从第二行取对应的value值
values = self.table.row_values(j)
for x in range(self.colNum):
s[self.keys[x]] = values[x]
r.append(s)
j += 1
return r
需要username和password两行数据。xlrd已经很全了…
需要继续改进的地方
现在倒回来来看还是很简单的…是踩在前辈们的肩膀上往上看的感觉。
- 可以考虑通过淘宝网站接口自动登录并下单,不走前端
- 通过微博登录总归不是最佳的解决方案,貌似异地登录的话还是会出现需要短信验证码的问题,所以解决登录的验证码还是不可逃避的!