selenium模块(浏览器自动化模块),和无头浏览器爬虫

看示例,模拟12306登陆(需要用到自己的12306账号密码,和自己的超级鹰账号密码和软件id)
selenium模块可以帮我我们便捷的爬取到页面中动态加载出来的数据
  
# 为了模拟人为登陆,需要阻塞程序
import time
# 使预览器自动化的模块
from selenium import webdriver
# 预览器自动化的动作链模块
from selenium.webdriver import ActionChains
# 截取图片的模块(pip install Pillow)
from PIL import Image


# 引入超级鹰的软件,用于提交验证码,不用动
import requests
from hashlib import md5

class Chaojiying_Client(object):

def __init__(self, username, password, soft_id):
self.username = username
password = password.encode('utf8')
self.password = md5(password).hexdigest()
self.soft_id = soft_id # 898175
self.base_params = {
'user': self.username,
'pass2': self.password,
'softid': self.soft_id, # 898175
}
self.headers = {
'Connection': 'Keep-Alive',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
}

def PostPic(self, im, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
}
params.update(self.base_params)
files = {'userfile': ('ccc.jpg', im)}
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files,
headers=self.headers)
return r.json()

def ReportError(self, im_id):
"""
im_id:报错题目的图片ID
"""
params = {
'id': im_id,
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
return r.json()



# 实例化一个预览器自动化对象(谷歌浏览器,对应的是谷歌版本对应的驱动程序,)
bro = webdriver.Chrome(executable_path=r'./chromedriver.exe')
# 打开的浏览器窗口最大化
bro.maximize_window()
# 访问12306登陆页面
bro.get('https://kyfw.12306.cn/otn/resources/login.html')
time.sleep(2)
# 因为这个页面是扫码登陆,所以我们自动化点击账号登陆
bro.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
# 定位到验证码图片的位置
yanzheng_addr = bro.find_element_by_xpath('/html/body/div[2]/div[2]/div[1]/div[2]/div[3]')
# 得到验证码图片的坐标{'x': 0, 'y': 0}

location = yanzheng_addr.location
print('起始坐标location',location)
# 得到验证码图片的尺寸,宽和高{'height': 188, 'width': 300}
size = yanzheng_addr.size
print('图片尺寸size',size)
# 构建一个元组数据结构,截取验证图片的起始坐标,结束坐标.(图片左上角坐标和右下角坐标)
tup = (location['x'], location['y'], location['x']+size['width'], location['y']+size['height'])


# 截取这个预览器打开网页的整张图片,并给一个路径+文件名
bro.save_screenshot('./all.png')
# 打开这个整张页面的图片
i = Image.open('./all.png')
# 在整张页面中通过坐标(构建的tup元组数据)截取验证码图片的数据,并把验证码图片保存
img = i.crop(tup)
img.save('./code.png')

# 固定写法,实例化超级鹰对象,参数分别是超级鹰的(!!!用户名,密码,自己创建软件的ID(同时会生产密钥))
chaojiying = Chaojiying_Client('xuebaohua', '123456xbh', '898175')
im = open('./code.png', 'rb').read()
result = chaojiying.PostPic(im, 9004) # 9004验证码类型()
print("返回的数据是一个字典result", result)
# 取出['pic_str']的数据,是'78,104|212,114',就是符合验证码规则的坐标
result = result['pic_str']

# 准备一个列表,用来构建数据结构[[x1,y1],[x2,y2],[x3,y3]],里面存放的就是验证码符合条件的坐标
lis =[]
# 判断符合条件的数量,最少有两个坐标的话,会有'|'
if '|' in result:
lis1 = result.split('|')
for i in lis1:
lis2 = i.split(',')
lis.append(lis2)
# 如果符合条件的只有一个的话(验证码只有一个符合条件),打印构建的lis数据
else:
lis.append(result.split(','))
print(lis)


# 得到要点击的坐标,然后以验证码图片位置()为全局坐标,依次点击符合条件的地方
for i in lis:
# 得到了坐标,可以创建动作链,用来点击验证码符合条件的地方(这一步必须在列表循环的里面)
action = ActionChains(bro)
x = i[0]
y = i[1]
# 以验证图片为全局坐标,以x,y坐标为目标位置,点击该位置.必须用下面的方法.
# perform()立即执行动作链
action.move_to_element_with_offset(yanzheng_addr,x,y).click().perform()
time.sleep(2)

# 点击完成之后,在标签id="J-userName"的input框中输入用户名
bro.find_element_by_id('J-userName').send_keys('!!!自己12306登录名')
time.sleep(2)
# 在标签id="J-password"的input框中输入用户名
bro.find_element_by_id('J-password').send_keys('!!!自己12306密码')
time.sleep(2)
# 点击登陆按钮
bro.find_element_by_xpath('//*[@id="J-login"]').click()


# time.sleep(2)
# bro.quit()

 

处理无头浏览器的代码

from selenium import webdriver
from lxml import etree
import time

# 无头浏览器,不会显示浏览器 from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') bro = webdriver.Chrome(executable_path='./chromedriver.exe',chrome_options=chrome_options) #让浏览器对指定url发起访问 bro.get('http://125.35.6.84:81/xk/') #获取浏览器当前打开页面的页面源码数据(可见即可得) page_text = bro.page_source time.sleep(2) tree = etree.HTML(page_text) # 药监局动态加载的公司名称,取第一个,打印一下 name = tree.xpath('//*[@id="gzlist"]/li[1]/dl/a/text()')[0] print(name) time.sleep(3) bro.quit()

  

 

 

posted on 2019-05-31 15:08  哎呀!土豆  阅读(653)  评论(0编辑  收藏  举报

导航