zoukankan      html  css  js  c++  java
  • python3爬虫-通过selenium登陆拉钩,爬取职位信息

    from selenium import webdriver
    from selenium.common.exceptions import NoSuchElementException
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver import ActionChains
    import time
    import json
    import os
    
    LG_URL_Login = "https://passport.lagou.com/login/login.html"
    cookies_path = "./cookies.json"
    
    
    class MyException(Exception):
        def __init__(self, status, msg):
            self.status = status
            self.msg = msg
    
    
    class LaGou:
        def __init__(self):
            self.login_status = False
            self.browser = None
            self.__init_browser()
    
        def __init_browser(self):
            '''初始化浏览器配置'''
            options = Options()
            options.add_experimental_option('excludeSwitches', ['enable-automation'])
            options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
            self.browser = webdriver.Chrome(options=options)
            self.browser.maximize_window()
            self.browser.implicitly_wait(3)
            self.wait = WebDriverWait(self.browser, 10)
            self.ac = ActionChains(self.browser)
            self.browser.get(LG_URL_Login)
    
        def __choose_login_mode(self):
            '''通过用户名,密码去登陆'''
            # 虽然默认是用户名密码登陆去,确保无误,还是自己点击一下
            self.wait.until(EC.presence_of_element_located((By.XPATH, "//*[@data-lg-tj-id='1Us0']")))
            self.browser.find_element_by_xpath("//*[@data-lg-tj-id='1Us0']").click()
    
        def __input_user_pwd(self, username, password):
            self.wait.until(EC.presence_of_element_located((By.XPATH, '//input[@placeholder="请输入密码"]')))
            self.wait.until(EC.presence_of_element_located((By.XPATH, '//input[@placeholder="请输入常用手机号/邮箱"]')))
            if not username:
                username = input("请输入常用手机号/邮箱>>:").strip()
            if not password:
                password = input("请输入密码>>:").strip()
            phone_ele = self.browser.find_element_by_xpath('//input[@placeholder="请输入常用手机号/邮箱"]')
            pwd_ele = self.browser.find_element_by_xpath('//input[@placeholder="请输入密码"]')
            # 输入账号
            phone_ele.clear()
            phone_ele.send_keys(username)
            # 输入密码
            pwd_ele.clear()
            pwd_ele.send_keys(password)
    
        def __chick_submit(self):
            self.wait.until(EC.presence_of_element_located((By.XPATH, "//*[@data-lg-tj-id='1j90']")))
            self.browser.find_element_by_xpath("//*[@data-lg-tj-id='1j90']").click()
    
        def __judge_login_successful(self):
            '''判断是否登陆成功'''
            # 判断class属性 user_dropdown
            try:
                self.browser.find_element_by_xpath("//*[@class='user_dropdown']")
                return True
            except NoSuchElementException:
                return False
    
        def __pull_down_page(self):
            '''首先拉钩它是没有懒加载的,所以我们只需要下拉一次就好了,所以while循环可以注释掉'''
            height = self.browser.execute_script("return document.body.scrollHeight;")
            js = "window.scrollTo(0, {});".format(height)
            self.browser.execute_script(js)
            return self.browser.page_source
            # while True:
            #     now_height = self.browser.execute_script("return document.body.scrollHeight;")
            #     if height == now_height:
            #         return self.browser.page_source
            #     js = "window.scrollTo({}, {});".format(height, now_height)
            #     self.browser.execute_script(js)
            #     height = now_height
    
        def __judge_ele_exist_by_xpath(self, xpath):
            '''通过xpath,判断是否存在这个元素'''
            try:
                self.browser.find_element_by_xpath(xpath)
                return True
            except NoSuchElementException:
                return False
    
        def __click_next_page(self):
            '''点击下一页'''
            self.wait.until(EC.presence_of_element_located((By.XPATH, "//span[@class='pager_next ']")))
            self.browser.find_element_by_xpath("//span[@class='pager_next ']").click()
    
        def __search_job(self, job_name):
            '''输入查询的job信息'''
    
            # 首先在搜索职位之前呢,会弹回一个框框,默认选择全国站,
            # 之所以会有这个框框,那是因为你不是在登陆状态下访问这个url,如果是登陆的,那么不会出现
            try:
                self.browser.find_element_by_link_text("全国站").click()
            except NoSuchElementException:
                pass
    
            # 搜索职位
            try:
                # self.wait.until(EC.presence_of_element_located((By.XPATH, "//*[@id='search_input']")))
                search_ele = self.browser.find_element_by_xpath("//*[@id='search_input']")
            except NoSuchElementException:
                search_ele = self.browser.find_element_by_xpath("//*[@id='keyword']")
            search_ele.click()
            search_ele.clear()
            search_ele.send_keys(job_name, Keys.ENTER)
    
        def __del__(self):
            # 10秒之后,关闭一些资源
            self.browser.close()
    
        def login(self, username: str = None, password: str = None, load_cookies: bool = True):
    
            if load_cookies and os.path.exists(cookies_path):
                # 使用保存再文件中的cookies去访问页面
                with open(cookies_path, "r", encoding="utf-8") as f:
                    cookies = json.loads(f.read())
    
                # 将cookies添加进去
                for cookie in cookies:
                    self.browser.add_cookie(cookie)
    
                # 访问登陆页面,如果是登陆页面表示cookie失效了,cookies没有的失效的情况就是重定向到首页
                self.browser.get(LG_URL_Login)
                if self.__judge_login_successful():
                    print("登陆成功....")
                    return True
                else:
                    print("cookies已经失效....")
                    # 删除刚刚添加的cookies
                    self.browser.delete_all_cookies()
            self.browser.refresh()
            self.__choose_login_mode()
            self.__input_user_pwd(username, password)
            self.__chick_submit()
    
            # 判断是否有极验验证码
            # 如果你多试几次,你会发现某次登陆不需要滑动验证码,所以说我们就利用这个,虽然并没有完全解决破解,但是目的最终还是达到了
            while True:
                time.sleep(1)
                if self.__judge_ele_exist_by_xpath("//div[@class='geetest_panel_box geetest_panelshowslide']"):
                    self.browser.find_element_by_xpath("//a[@class='geetest_close']").click()
                    time.sleep(1)
                    self.browser.find_element_by_xpath("//*[@data-lg-tj-id='1j90']").click()
                    continue
                else:
                    break
    
            if self.__judge_login_successful():
                self.login_status = True
                # 登陆成功,将cookies保存起来
                with open("./cookies.json", "w", encoding="utf-8") as f:
                    f.write(json.dumps(self.browser.get_cookies()))
                print("登陆成功")
                return True
            else:
                print("登陆失败,请检查你的用户名或密码")
                return False
    
        def get_job_info(self, job_name: str = None, is_filter: bool = False):
            '''用于获取到查询的job'''
            if not self.login_status:
                self.browser.get("https://www.lagou.com/")
            if not job_name:
                job_name = input("请输入查询job的名称>>:").strip()
    
            self.__search_job(job_name)
    
            if is_filter:
                # 过滤这个功能不忙实现
                pass
            # 这里开始就是进行翻页操作了,以及对数据的处理
            page = 1
            while True:
                print("爬取工作职位为>>{}   第{}页数据".format(job_name, page))
                # 获取到完毕的页面源码,然后进行提取信息的操作
                page_source = self.__pull_down_page()
                print(page_source)
                # 信息提取完毕,进行翻页操纵
                if not self.__judge_ele_exist_by_xpath("//span[@class='pager_next ']"):
                    print("{} 工作职位爬取完毕...".format(job_name))
                    break
                self.__click_next_page()
                time.sleep(2)
    
                # 点击完毕下一页,可能遇到一些反扒措施
                if self.browser.current_url == "https://passport.lagou.com/login/login.html":
                    self.login()
    
                page += 1
    
    
    if __name__ == '__main__':
        lagou = LaGou()
    
        username = ""
        password = ""
        lagou.login()

    保存的cookies只能适用于本次浏览器访问,你关闭浏览器后,再使用cookies登陆,会显示失效。

    但我手动登陆拉钩,关闭浏览器。再次访问还是能够访问到我自己的信息。cookies是没有失效的,那估计就是我设置cookies那里有问题吧。

  • 相关阅读:
    重构引发的开发思考
    JS-正则表达式
    中文数字转数值
    框架-VuePress(未完)
    HTML-表格
    框架-Vue 2.*的补充
    框架-Vue Class Component tsx 支持(vue-tsx-support V2.2.0)
    CSS-flex
    框架-Vue Class Component 官方支持(vue 2.*、Vue Class Component、vue-property-decorator 9.0.2、vuex-class 0.3.2)
    vue-router:2020-03-26
  • 原文地址:https://www.cnblogs.com/zhuchunyu/p/10785364.html
Copyright © 2011-2022 走看看