这一周多的时间主要做一个自动登陆新浪然后刷票的工具,这里做个mark。
刚开始用java做,主要是用到java的httpclient去进行模拟登陆,在登陆新浪微博上,网上有现成的代码,可以看“java模拟登陆微博完整版”,一些逻辑上的可以看这个“微博模拟登陆研究”,但是我并不是要模拟登陆新浪微博,我需要登陆的是“调查汇总页”,在这里我参考“微博模拟登陆研究”所说的过程研究了登陆过程中传输的网络数据信息,但是在第一次跳转后得到的html数据很奇怪,里面抓出的重定向ur再次跳转后得到的东西很奇怪吧,反正不会处理了,不知道是不是前面的抓包分析有问题,希望有会的人指导一下。这里面也遇到过返回html乱码问题,通过jsoup来分析页面源码,利用xpath路径来定位元素等,每一个都是很重要的知识。
之后用htmlunit来做,这是一个直接通过模拟点击元素控件来进行操作页面,模拟登陆等这些操作的,但是页面似乎只能通过id和name来获取元素和按钮,我通过xpath路径获取按钮,但是跳转失败,通过标签名获取元素,跳转也失败,可能很多理解的还不清楚。
后来同学跟我说python有个很好用的工具splinter,可以模拟人工操作浏览器。然后我发现这个确实简单好用。
只需要导入这个包就好。这里插一段代码。
<span style="font-size:24px;"><span style="font-size:18px;">def vote(user):
key = user[0] #账号
value = user[1] #密码
user_agent = random.choice(user_agent_list) #浏览器
'''
ip, port = random.choice(ip_pool_list) #ip代理
ip = str(ip)
port = int(port)
#print(ip)
#print(port)
proxy_parameter = {} # 存放代理信息
proxy_parameter["network.proxy.type"] = 1 #手动配置ip
proxy_parameter["network.proxy.http"] = ip
proxy_parameter["network.proxy.http_port"] = port
proxy_parameter["network.proxy.ssl"] = ip
proxy_parameter["network.proxy.ssl_port"] = port
browser = Browser(profile_preferences=proxy_parameter)
'''
browser = Browser()
url = "https://login.sina.com.cn/signup/signin.php?entry=sso" #登陆地址
browser.visit(url)
#browser.find_by_id('JS_Login_Btn').click()
try:
time.sleep(sleep_time)
browser.find_by_xpath('//input[@name="username"]').fill(key) #有些账号需要验证码,这里需要两种
#办法去应对
browser.find_by_xpath('//input[@name="password"]').fill(value)
except:
browser.quit()
time.sleep(sleep_time)
try:
button = browser.find_by_xpath('//input[@class="btn_submit_m"]')
#print(button)
button.click()
time.sleep(sleep_time)
except:
pass
try:
browser.visit(url_toupiao)
time.sleep(sleep_time)
for each in param_list:
browser.find_by_xpath('//input[@value="{number}"]'.format(number=int(each))).click() #投票选项点击
button7 = browser.find_by_id('JS_Survey_Submit') #提交投票结果
button7.click()
time.sleep(sleep_time)
global COUNT_SUCCESS
COUNT_SUCCESS = COUNT_SUCCESS + 1
#print("当前已经成功投票{number}张".format(number = COUNT_SUCCESS))
except:
browser.quit()
print("当前已经成功投票{number}张".format(number = COUNT_SUCCESS))
browser.quit()</span></span>
在做这个的时候有个问题就是在打开一个新的页面的时候然后对这个新页面进行操作会出错,原因就是代码仍然定位在最早的页面,这个时候去splinter官网资料可以找到相关文档,好吧,那都是英文的,操蛋。因为splinter是继承自selenium的,所以也可以从selenium的东西找到一些可用的,看这里selenium学习笔记,在这里你可以发现,卧槽,python可以通过这么多东西来定位查找到你需要的元素,好方便。这时候你会发现这个函数driver.switch_to_window(),他会根据窗口名来选择窗口,那么怎么知道窗口名呢?browser.windows这个函数可以获得所有程序打开的窗口,并按打开顺序放在列表里。如果我们需要获得最后打开的窗口名,那就是browser.windows[-1].name,关闭当前窗口就是browser.driver.close()。
当然还有关键的设置代理。新浪投票很恶心,有些投票的是按ip算的,有些呢,你给这个选项投,他给别的选项涨,真特么搞不懂他啥机制。
下面这段就是设置代理:
<span style="font-size:24px;"><span style="font-size:18px;">ip, port = random.choice(ip_pool_list) #ip代理
ip = str(ip)
port = int(port)
#print(ip)
#print(port)
proxy_parameter = {} # 存放代理信息
proxy_parameter["network.proxy.type"] = 1 #手动配置ip
proxy_parameter["network.proxy.http"] = ip
proxy_parameter["network.proxy.http_port"] = port
proxy_parameter["network.proxy.ssl"] = ip
proxy_parameter["network.proxy.ssl_port"] = port
browser = Browser(profile_preferences=proxy_parameter)</span></span>
这个代理设置应该是对的,因为我在其他需要验证码的登陆投票代码里试过,但是在这里有问题,不知道问题出在哪,希望有人能给我指点。
然后是把这个脚本打包,打包有几种方式,可以看将python脚本打包成可执行文件,显然这里是要将它打包成可执行文件,也就是在别的环境下运行不需要装python运行环境和相关包。先装一个pyinstaller,就是用pip install pyinstaller命令,然后利用这个库对脚本进行打包,也就是在cmd下和myPy.py同目录下的路径里运行pyinsatller myPy.py,然后可以看到增加了一个dist目录,该目录下就是可执行文件,然后需要把配置文件和数据包等外部文件放到跟exe同目录下,然后就可以直接运行exe文件了。打包过程中也有错误,参考这里pyinstaller相关错误,在这里用了这个“在python代码中读取文件时文件路径为stopwordsFile=r"data/stopwordsFile.txt"就可以了”,然后解决了。
这里暂时mark到这里,结果简单,过程曲折,maybe这里也还有一些问题,希望被指导。最后mark两个相关链接:简单刷票系统(突破ip限制)和基于httpclient简单刷票器实现。