selenium+chormeDriver移动鼠标模拟点击百度

seo教程 litianseo 1年前 (2019-06-11) 322次浏览 已收录 0个评论

爬取 ajax 数据的两种方式

  • 分析接口
  • 使用 selenium
    释义:1.在不重载整个网页界面的情况下,新增数据展示。2.在浏览器中 查看网页源代码,不能看到 ajax 加载的数据(举个例子,点击加载更多,还是还是不能再网页源代码中查看到数据)
selenium

Selenium 是一个用于 Web 应用程序测试的工具。主要解决 javascript 渲染的问题
Selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。
支持的浏览器包括 IE,Mozilla 和 Firefox 等。
这个工具的主要功能包括:测试与浏览器的兼容性,测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能,创建衰退测试检验软件功能和用户需求。

chromedirver 操作网页

chromedirver 下载对应版本到 python 安装目下的 scrprts 中
云盘下载,提取码:a1wd
简单测试

from selenium import webdriver
borswer = webdriver.Chrome()

就能打开一个 google 浏览器了。

selenium 详解

参考资料-selenium 详解

定位元素

from selenium import webdriver
import time
from lxml import etree
broswer=webdriver.Chrome()
broswer.get("https://www.baidu.com/")
# time.sleep(5)
# broswer.close()
#inputTag=broswer.find_element_by_id('kw')
#inputTag=broswer.find_element_by_class_name('s_ipt')
#inputTag=broswer.find_element_by_xpath('//input[@class="s_ipt"]')
#inputTag=broswer.find_element_by_css_selector('#kw') #浏览器 copy,选择 selector 生成
# inputTag=broswer.find_element_by_xpath('//*[@id="kw"]')#浏览器 copy,选择 xpath 生成,需加//
# inputTag.send_keys("python")
#为了快速解析数据,推荐 lxml 拉埃解析,底层 c 语言,解析小兰高,
#如果是对元素进行操作,插入输入值等,就必须使用 selenium 的方法了
html=etree.HTML(broswer.page_source)
btn_text=html.xpath("//input[@id='su']/@value")[0]
print(btn_text)

操作表单元素

常见的 input type=’text/password/eamil/num’
input type=’submit’
intput type=’checkbox’,

  • 填入数据 send_keys(“”)
  • 清除数据 clear()
  • click()点击
  • select 元素不能点击,一般包装一个 Select()
from selenium.webdriver.support.select import Select
...
#包装
selectTag=Select(broswer.find_element_by_class_name("XXX"))
#根据索引
selectTag.select_by_index("XX")
#根据值
selectTag.select_by_value("XXX")
#根据文字
selectTag.select_by_visible_text("XXX")
#取消所有选项
selectTag.deselect_all()

行为链接

有时候在页面的操作有很多步,这时可使用行为链,ActionChans 来完成

举个例子:
百度界面,输入 python,点击按钮进行搜索。一般方式如下

inputTag=broswer.find_element_by_xpath('//*[@id="kw"]')#浏览器 copy,选择 xpath 生成,需加//
inputTag.send_keys("python")
btnTag=broswer.find_element_by_xpath("//input[@id='su']")
btnTag.click()

采用行为链的方式

inputTag=broswer.find_element_by_xpath('//*[@id="kw"]')#浏览器 copy,选择 xpath 生成,需加//
btnTag=broswer.find_element_by_xpath("//input[@id='su']")
actions=ActionChains(broswer)
#移动到输入框中上
actions.move_to_element(inputTag)
#进行输入值
actions.send_keys_to_element(inputTag,"Python 书籍")
#移动到搜索按钮上
actions.move_to_element(btnTag)
#点击搜索按钮
actions.click(btnTag)
#确认
actions.perform()

其他鼠标相关操作

  • click_and_hold(e):点击但不松开鼠标
  • content_click(e):右击鼠标
  • double_click(e):双击
    更多参考官网

cookie 操作

  1. 获取所有的 cookie
    x.get_cookies()
  2. 根据 cookie 的 key 获取 value
    x.get_cookie(key)
  3. 删除所有 cookie
    delete_all_cookies()
  4. 删除某个 cookie
    x.delete_cookie(key)

页面等待

不确定某个原始何时加载出来

  • 隐式等待
broswer.implicitly_wait(10)
  • 显示等待
ele = WebDriverWait(broswer, 10).until(EC.presence_of_element_located(By.CSS_SELECTOR, "#kw"))
    ele.send_keys("python")

切换页面

有时候窗口中有很多的子 tab 页面,这时候是需要进行切换的,switch_to.winow来进行切换,具体切换都哪个界面,可以从driver.window_handles中找到

broswer.get("https://www.baidu.com/")
broswer.execute_script("window.open('https://www.douban.com/')")
print(broswer.current_url)#当前还是 baidu
broswer.switch_to.window(broswer.window_handles[1])
print(broswer.current_url)#当前是 douban

使用代理

网页查看 ip 的网址http://httpbin.org/ip

options=webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://61.189.242.243:55484")
broswer = webdriver.Chrome(chrome_options=options)
broswer.get("http://httpbin.org/ip")

补充 webelement

获取属性,保存图片等

broswer = webdriver.Chrome()
broswer.get("http://www.baidu.com")
btn=broswer.find_element_by_id("su")
print(btn.get_attribute("value"))
broswer.save_screenshot("baidu.jpg")

实战 爬取拉钩网

拉勾网典型的使用 ajax 技术网站

https://www.lagou.com/jobs/list_python?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=
selenium+chormeDriver移动鼠标模拟点击百度
image.png

一,分析接口,使用 requests 来请求

问题:

selenium+chormeDriver移动鼠标模拟点击百度
image.png

需要加Referer,这是拉钩设置的反扒机制,如果爬取其他网站过程中,还是获取不到数据,就把 headers 中的都添加进去。

import requests

from  lxml import etree

def get_page():
    url="https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false"
    proxy = {
        'http': '180.110.7.234:3128'
    }
    head={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
          "Referer":"https://www.lagou.com/jobs/list_python?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput="}
    data ={
        'first':"false",
        'pn':1,
        'kd':'python'
    }
    response=requests.post(url,headers=head,data=data,proxies=proxy)
    print(response.json())
def main():
    get_page()
if __name__ == '__main__':
    main()

这样子就能拿到返回的 json 数据啦,就可以自己取数据啦。

    for x in range(1, 10):
        time.sleep(2)
        response=requests.post(url,headers=head,data=data,proxies=proxy)
        print(response.json())

注意在循环遍历爬取的时候,又被反扒了,加了头部信息。才又成功。

selenium+chormeDriver移动鼠标模拟点击百度
image.png

使用代理,可以解决问题
获取详情,全部代码参考

import requests
from lxml import etree
import time
head = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
    "Referer": "https://www.lagou.com/jobs/list_python?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=",
    "Origin": "https://www.lagou.com",
    }
def get_page_url():
    url = "https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false"
    data = {
        'first': "false",
        'pn': 1,
        'kd': 'python'
    }
    for x in range(1, 2):
        data['pn'] = x
        response = requests.post(url, headers=head, data=data)
        try:
            result = response.json()
            postions = result["content"]["positionResult"]['result']
            #数量太多,最后延时,
            for pos in postions:
                postion_id = pos["positionId"]
                pos_url = "https://www.lagou.com/jobs/{}.html".format(postion_id)
                parse_p_details(pos_url)
                break
        except Exception as e:
            print(e.args)
def parse_p_details(url):
    response=requests.get(url,headers=head)
    htmlEle=etree.HTML(response.text)
    compony=htmlEle.xpath("//*[@id='job_company']/dt/a/div/h2/text()")[0]#使用浏览器一键复制的
    xinshui=htmlEle.xpath("/html/body/div[3]/div/div[1]/dd/p[1]/span[1]/text()")[0]#使用浏览器一键复制的
    desc="\n".join(htmlEle.xpath("//dd[@class='job_bt']//p/text()"))#自己判断的,获取该类下的所有段落的文本
    print(desc)
def main():
    get_page_url()
if __name__ == '__main__':
    main()

最佳方式使用 seleinum

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
from lxml import etree
"""
流程:1.打开当前页,获取每个链接。循环获取每个链接中的详情内容
2.完毕之后,点击下一页,重复 1

"""
class LanGou(object):
    def __init__(self):
        self.marks=[]
        self.broswer=webdriver.Chrome()
        self.broswer.implicitly_wait(20)
        #该地址就是网址实际地址,不用在 network 寻找
        self.url="https://www.lagou.com/jobs/list_python?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput="
    def run(self):
        #循环遍历每一页,最好睡几秒
            self.broswer.get(self.url)
        while True:
           
            #page_source 相当于源代码啦
            source=self.broswer.page_source
            # WebDriverWait(driver=self.broswer, timeout=10).until(
            #     EC.presence_of_element_located((By.XPATH, "//div[@class='pager_container']/span[last()]")))
            #self.parse_one_page(source)
            #上面是爬取完一页
            #进行下一页,翻页
            #第三部,请求完第一页,进入第二页,知道不能点击
            next_page_btn =self.broswer.find_element_by_xpath("//div[@class='pager_container']/span[last()]")
            if "pager_next_disabled" in next_page_btn.get_attribute("class"):
                break
            else:
                print("page")
                next_page_btn.click()
            time.sleep(2)

   #第一步,请求界面,
    def parse_one_page(self,sourse):
        htmlEle=etree.HTML(sourse)
        #1 页有多少个职位就有好多连接
        links=htmlEle.xpath("//a[@class='position_link']/@href")
        for detail_url in links:
            self.request_detail(detail_url)
            time.sleep(2)

   #第二步,循环请求详情界面数据,窗口切换,关闭,切换到列表页
    def request_detail(self,url):
        #需要打开新的界面,在详情页中没有下一页按钮
        #self.broswer.get(url=url)
        self.broswer.execute_script("window.open('{}')".format(url))
        self.broswer.switch_to.window(self.broswer.window_handles[1])
        source=self.broswer.page_source
        self.parse_detail(source)
        #关闭当前详情页面,切换到列表页
        self.broswer.close()
        self.broswer.switch_to.window(self.broswer.window_handles[0])

#注意 L 使用显示等待,xpath 解析,不需要写最后的 text(),是获取不到的,一般解析需要 text()
    def parse_detail(self,source):
        htmlEle = etree.HTML(source)
        compony = htmlEle.xpath("//dl[@class='job_company']/dt//h2/text()")[0].strip()
        xinshui = htmlEle.xpath("//span[@class='salary']/text()")[0]
        desc = "\n".join(htmlEle.xpath("//dd[@class='job_bt']//p/text()"))  # 获取该类下的所有段落的文本
        mark = {
            'compony': compony.strip(),
            'xinshui': xinshui.strip(),
            'desc': desc
        }
        self.marks.append(mark)
        print("*" * 20)
        print(mark)



if __name__ == '__main__':
    spider=LanGou()
    spider.run()

注意:重复在第二页,原因把 get(url)放在了 While True 中,导致每次要刷新,所以在 1,2,页切换

 


32w.net , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:http://www.32w.net/baidukuaipai/305.html
selenium+chormeDriver移动鼠标模拟点击百度
喜欢 (0)
[576801182@qq.com]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址