欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python3爬虫-通过selenium登陆拉钩,爬取职位信息

程序员文章站 2022-12-26 14:51:13
保存的cookies只能适用于本次浏览器访问,你关闭浏览器后,再使用cookies登陆,会显示失效。 但我手动登陆拉钩,关闭浏览器。再次访问还是能够访问到我自己的信息。cookies是没有失效的,那估计就是我设置cookies那里有问题吧。 ......
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那里有问题吧。