从零开始用Selenium 模拟人工点击
标签(空格分隔): Selenium 爬虫 python chromedriver xpath
安装开发环境
在win10下面搞的
安装python
下载安装,我下载到的版本是2.7.15,所以pip也不用装了(2.7.9+和3.4+版本的后续版本只要装了python就有pip,其它版本则要手工安装)
安装IDE
多年前用python搞过一下下爬虫,因为没用专门的编辑器和调试器,吃了点苦头,所以开始之前找了一下IDE,看了一下资料,最后选了pycharm Community Edition。项目的创建,文件的创建和其它IDE没有什么区别,看菜单就知道怎么操作;调试的功能也比较完善。用了一下,感觉还不错
安装chromedriver
我喜欢chrome,所以选了chromedriver(Selenium用driver来操作chrome和firefox等浏览器,不同的浏览器有不同的driver,等会看代码就能体会什么是driver了),下载后解压缩,随便放哪都行,没必要设置环境变量,因为可以通过代码指定路径,这里提前看看代码体会一下
webdriver.Chrome(executable_path='/path/to/chromedriver.exe')
安装selenium
pip install Selenium
中文环境可能会出现“UnicodeDecodeError: 'ascii' codec can't decode byte 0xd6 in position 7: ordinal not in range(128)”的报错,在/path/to/python/Lib/ntpath.py中import代码之后加上
reload(sys)
sys.setdefaultencoding('gb2312')
找个简单的例子试一下
from selenium import webdriver
options = Options()
options.binary_location = ‘/path/to/chrome.exe’
driver = webdriver.Chrome(executable_path='/path/to/chromedriver.exe',chrome_options=options)
driver.get('http://www.google.com/xhtml');
driver.quit();
开始
我的项目用到的就是点击和填表操作,所以这里模拟点击页面元素和填写表格的操作。
在开始之前先介绍一下怎么找到需要操作的页面元素。以前搞过一下下爬虫,那时候使用xpath来确定需要操作的页面元素,但是不记得那时候怎么找xpath,因为那个时候还没有做工作记录的习惯。
不过因祸得福,发现了一个更加方面的确定xpaht的方法:F12打开chrome的DevTools,定位元素(这里就不详细讲怎么用devtools定位元素了,因为这是很基础的操作,不明白的同学只要问问搞前端的,肯定都知道,要讲清楚还要截图挺麻烦的,反正很简单的就是了),右键节点,Copy->Copy Xpath,这样就ok了,相当方便。
ps:要在selenium自动打开的而不是自己手工打开的chrome上面用devtools找xpath,因为自己手工打的开chrome会加载很多你安装过的插件,这些插件有可能会修改dom,从而导致找不到页面元素真实的xpath;此外如果只要鼠标停留在一个div上就能进行点击从而不知道真正应该点击div中的哪个元素的时候,随便随几个就能找到真正的要点击的元素了(这个看不懂不要紧,碰到这个问题的时候自然就明白了)
模拟点击
找到xpath之后用一条代码就能模拟点击元素了
driver.find_elements_by_xpath("你找到的xpath")[0].click()
为什么会有"[0]"?这是因为find_elements_by_xpath找到的东西貌似都是list,不用"[0]"会报 AttributeError: 'list' object has no attribute 'click' 的错误
模拟填表
同样也是先找xpath
driver.find_elements_by_xpath("你找到的xpath")[0].send_keys(u'测试');
send_keys的参数前面那个 'u' 表示unicode,中文常量前面要加个 u ;如果这条代码执行后表格没变化,说明正在操作的input可能本来就不支持中文;另外为了避免代码的编码问题,应该在python文件的开头加上
#!/usr/bin/env python
# -*- coding: utf-8 -*-
其它
怎么才能不打开浏览器
如果用Selenium模拟人工点击是用在爬虫中,那么是不希望打开浏览器的,这时候(以chrome为例)只要配置一下webdriver就可以了
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def ConfigDriver():
options = Options()
options.add_argument('--headless') #以所谓的headless模式打开chrome
return options
def BuildDriver():
return webdriver.Chrome(chrome_options=ConfigDriver())
driver = BuildDriver()
ps:chrome的headless模式完全能替代网上还有很多资料说的phantomJS,新一点版本的selenium已经不支持phantomJS了,所以还是别搞phantomJS比较好
关于代理服务
网上虽然有很多免费的代理,github上面也有好多star的proxy pool(比如 https://github.com/jhao104/proxy_pool 和 https://github.com/SpiderClub/haipproxy),但是如果项目是商用的,可能还是避免不了花钱买代理池。
知乎有篇文章(说说代理IP哪家好? https://www.zhihu.com/question/55807309),我试了一下里面的讯代理和蘑菇代理,两个都用包一天(讯代理9块,蘑菇6块),都还可以。给了钱之后可以根据订单生成API(讯代理还有所谓的动态代理而不是API的方式,有兴趣可以看看上面提到的知乎文章或者去他们官网一开就知道了)。
API调用返回结果可以是json或者txt,在生成API的时候可以自己选择,我选了json,所以就有python里面怎么分析json的问题,python对json的解析是非常容易的,比如有个变量data是一下json
{"code":"0","msg":[{"port":"27914","ip":"27.152.153.108"},{"port":"49382","ip":"115.226.13.1"},{"port":"43444","ip":"183.163.164.78"},{"port":"48995","ip":"125.118.242.245"},{"port":"32690","ip":"183.142.18.57"}]}
用下面这种形式就能访问
data["msg"][0]["ip"]
data["msg"][0]["port"]
以此类推
python里面怎么读ini配置
不管什么程序,读配置都是标配了,python读ini配置是非常方便的,看一个例子就明白了
config.ini
[Paths]
chrome=/path/to/chrome.exe
Configure.py
import ConfigParser
Config = ConfigParser.ConfigParser()
Config.read("config.ini")
Config.sections()
def ConfigSectionMap(section):
dict1 = {}
options = Config.options(section)
for option in options:
try:
dict1[option] = Config.get(section, option)
if dict1[option] == -1:
print("skip: %s" % option)
except:
print("exception on %s!" % option)
dict1[option] = None
return dict1
def ConfigGetChromePath():
return ConfigSectionMap("Paths")['chrome']
尾声
上文的结论绝大部分都是google和参考stackoverflow中的资料的,参考的链接太多,所有就偷个懒不列了
对于下拉列表应该点击哪个,表格应该填写什么东西,还需要写个后台程序来配置,等写好了再把文档写一下,待续。