【项目开发日志记录】-J项目-V2-已完成

项目开发过程中的知识点收获

用csv文件存储数据时,同步自定义设置表头的代码实现

要点:在写入csv文件时,设置参数header。写入顺序即为自身设置的顺序

form_header = ['职位名称','职级','职位族']
数据 = pd.DataFrame({'职位名称':job_name_list,'职级':job_level_list,'职位族':job_family_list})
数据.to_csv('d:/职位信息.csv',mode='a',header=form_header,encoding='ANSI')
DataFrame中的字典结构数据,键名后面的值的数据类型必须是列表的类型。
数据 = pd.DataFrame({'职位名称':job_name_list,'职级':job_level_list,'职位
函数调用报错-name 'children_page' is not define

解决方式:把自己定义写好的函数放在主函数的最前面。因为程序编译器的解析,是从上到下进行编译执行的。上述错误即是因为函数没有定义的问题。

子页面链接点击爬取问题
 browser = webdriver.Chrome()
 browser=job_name.click()
 print(browser)

在子函数中,尝试新建浏览器对象来进行详情页面的关键信息抓取,但点击列表页超链接后,并未有接收到任何返回值。

子页面链接点击爬取后的返回值问题

现象:返回值必须含有浏览器对象,否则在下一次运行函数,会出现如下报错;

StaleElementReferenceException: stale element reference: element is not attached to the page document
  (Session info: chrome=97.0.4692.71)
def children_page(job_name):
    job_name.click()
    页面 = 浏览器对象.window_handles
    #print(页面)
    #浏览器对象切换到所有打开
    浏览器对象.switch_to.window(页面[-1])
    time.sleep(3)
    job_name=浏览器对象.find_element_by_xpath('//*[@id="showTab"]/div[3]/div[1]/h1/label[1]')
    work_place=浏览器对象.find_element_by_xpath('//*[@id="addressDiv"]/label[1]')
    update=浏览器对象.find_element_by_xpath('//*[@id="showTab"]/div[3]/div[1]/ul/li[1]/label')
    department=浏览器对象.find_element_by_xpath('//*[@id="jobDeptLabel"]')
    job_family=浏览器对象.find_element_by_xpath('//*[@id="showTab"]/div[3]/div[3]/ul/li[5]/label')
    job_level=浏览器对象.find_element_by_xpath('//*[@id="jobLevelTitle"]')
    job_duty=浏览器对象.find_element_by_xpath('//*[@id="mainBusiness"]')
    job_request=浏览器对象.find_element_by_xpath('//*[@id="demand"]')

    print(job_name.text)
    print(work_place.text)
    print(update.text)
    print(department.text)
    print(job_family.text)
    print(job_level.text)
    print(job_duty.text)
    print(job_request.text)
    浏览器对象.close()
    time.sleep(2)
    #将浏览器对象切回到原有列表页这一点很重要
    浏览器对象.switch_to.window(页面[0])
    return 浏览器对象

函数返回值如果有多个,其实返回的是元组。Python的函数返回多值其实就是返回一个tuple,但写起来更方便。

函数返回多个值,只取部分值

一个常见的惯例是使用“_“作为要忽略的元组元素的变量名。例如:

def f():
    return 1, 2, 3

_, _, x = f()
异常问题:下拉加载多项之后,点击详细页的加载方式失效

具体报错代码如下:

ElementClickInterceptedException: element click intercepted: Element ... is not clickable at point (168, 10). Other element would receive the click: 
  • ...
  • (Session info: chrome=97.0.4692.71)
    完整成功代码如下
    import requests
    import json
    import pandas as pd
    import time
    import xlwt
    from lxml import etree
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver import  ActionChains # 动作链
    
    
    #定义抓取详情页的函数-直接点击子页面爬取的方式
    def children_page(button):
        #利用动作链将浏览器页面定位到链接点击处
        ActionChains(浏览器对象).move_to_element(button).perform()  
        button.click()
        页面 = 浏览器对象.window_handles
        
        #浏览器对象切换到列表页打开
        浏览器对象.switch_to.window(页面[-1])
        time.sleep(3)
        job_name=浏览器对象.find_element_by_xpath('//*[@id="showTab"]/div[3]/div[1]/h1/label[1]')
        work_place=浏览器对象.find_element_by_xpath('//*[@id="addressDiv"]/label[1]')
        update=浏览器对象.find_element_by_xpath('//*[@id="showTab"]/div[3]/div[1]/ul/li[1]/label')
        department=浏览器对象.find_element_by_xpath('//*[@id="jobDeptLabel"]')
        job_family=浏览器对象.find_element_by_xpath('//*[@id="showTab"]/div[3]/div[3]/ul/li[5]/label')
        job_level=浏览器对象.find_element_by_xpath('//*[@id="jobLevelTitle"]')
        job_duty=浏览器对象.find_element_by_xpath('//*[@id="mainBusiness"]')
        job_request=浏览器对象.find_element_by_xpath('//*[@id="demand"]')
       # print(job_name.text)
        dir_data={
            'goal_job_name':job_name.text,
            'goal_work_place':work_place.text,
            'goal_update':update.text,
            'goal_department':department.text,
            'goal_job_family':job_family.text,
            'goal_job_level':job_level.text,
            'goal_job_duty':job_duty.text,
            'goal_job_request':job_request.text
            }
        浏览器对象.close()
        time.sleep(2)
        #将浏览器对象切回到原有列表页这一点很重要
        浏览器对象.switch_to.window(页面[0])
        return 浏览器对象,dir_data
      
    #主程序
    网址 = 'http://XXXXXhtml'
    UA伪装 = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36'}
    proxies={
    'http':'http://XXXX@XXXX',
    'https':'XXXX@pXXXX'
    }
    
    #无头模式配置
    '''
    chrome_options=webdriver.ChromeOptions()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    浏览器对象 = webdriver.Chrome(chrome_options=chrome_options)
    '''
    
    # 获取[浏览器]的实例化对象
    浏览器对象 = webdriver.Chrome()
    # 使用浏览器打开网址
    浏览器对象.get(网址)
    #因为网络存在延迟,所以需要延缓几秒打开网页,否则可能存在元素未完全加载的情况
    time.sleep(5)
    浏览器对象.find_element_by_id('poolSelectCheckTips').click()
    浏览器对象.find_element_by_id('btnconfirm').click()
    time.sleep(3)
    #job_name = 浏览器对象.find_element_by_xpath('//div[@class="centent_l fl"]//h3/a/@title')
    #实测发现先点击职位族,再点击职级抓取的数据相对会更准确一些。两者顺序调换后,抓取的数据中前面几个会有技术族的信息。
    #筛选条件点击-职位族
    浏览器对象.find_element_by_xpath('//dd[@id="positionList"]//a[@data="J03"]').click()
    time.sleep(5)
    #筛选条件点击-职级
    浏览器对象.find_element_by_xpath('//dd[@id="joblevelList"]/a[@data="13,14"]').click()
    #点击之后暂缓3秒,等待数据加载
    time.sleep(5)
    
    #print(type(job_name))
    job_name_list=[]
    job_level_list=[]
    job_family_list=[]
    
    dir_data_list=[]
    goal_job_name_list=[]
    goal_work_place_list=[]
    goal_update_list=[]
    goal_department_list=[]
    goal_job_family_list=[]
    goal_job_level_list=[]
    goal_job_duty_list=[]
    goal_job_request_list=[]
    
    
    #列表页的元素获取
    #job_level=浏览器对象.find_element_by_xpath('//div[@class="centent_l fl"]/p')
    #job_family=浏览器对象.find_element_by_xpath('//div[@class="centent_l fl"]/div')
    #job_link1=job_name.get_attribute('href')
    #job_link='http://w3.huawei.com'+job_link1
    
    
    #将页面滚动条拉到页面的底部
    i=1
    while i!=80:
        js="var q=document.documentElement.scrollTop=100000"
        浏览器对象.execute_script(js)
        time.sleep(2)
        i=i+1
    print(i)
    
    
    #初始未有翻页的超链接抓取
    #job_name = 浏览器对象.find_elements_by_xpath('//div[@class="centent_l fl"]//h3/a')
    #开始有翻页后的链接抓取
    button = 浏览器对象.find_elements_by_xpath('//div[@class="centent_l fl"]//h3/a')
    #print(button)
    #print(job_name[0],job_name[1])
    for element in button:
        _,x=children_page(element)
        print(x)
        #print(x.values())
        goal_job_name_list.append(x['goal_job_name'])
        goal_work_place_list.append(x['goal_work_place'])
        goal_update_list.append(x['goal_update'])
        goal_department_list.append(x['goal_department'])
        goal_job_family_list.append(x['goal_job_family'])
        goal_job_level_list.append(x['goal_job_level'])
        goal_job_duty_list.append(x['goal_job_duty'])
        goal_job_request_list.append(x['goal_job_request'])
    
    #将列表字典中的数据进行提取,准备文件储存
    print(goal_job_name_list)
    print(goal_work_place_list)
    数据 = pd.DataFrame({'职位名称':goal_job_name_list,'工作地':goal_work_place_list,'发布时间':goal_update_list,'岗位部门':goal_department_list,'职位族':goal_job_family_list,'职级':goal_job_level_list,'岗位职责':goal_job_duty_list,'任职要求':goal_job_request_list,})
    数据.to_excel('d:/job_information.xlsx')
    #数据.to_csv('d:/职位信息.csv',mode='a',header=form_header,encoding='ANSI')
    

    附录-网页加载过程中的一些逻辑分析(已无太大意义)

    项目开发-inner
    • 目标网站及基本特征数据

    • 网站特点及加载逻辑分析

      • 刚刚进入网站时,会发生链接的重定向跳转。弹出一个框框让勾选,比较讨厌

      • 网页是属于Ajax异步加载的,通过下拉加载更多,会发送Ajax请求。

      • 点击职级时,出现的异步加载链接:http://w3.huawei.com/ihrm/services/hometalent/portal/newPortal/findAllJobForPortal/10/1?jobLevel=13%2C14&orderBy=LAST_UPDATE_DATE_DESC&someondeCount=17

      • 点击职位族时,出现的异步加载链接:http://w3.huawei.com/ihrm/services/hometalent/portal/newPortal/findAllJobForPortal/10/1?jobFamily=J19&orderBy=LAST_UPDATE_DATE_DESC&someondeCount=19

      • 【规律发现】:在这个Ajax请求里有发现,职级为obLevel=13%2C14这种,职位族为jobFamily

    • 尝试获取日志

      • 2022/1/10-利用XPath获取数据当前存在问题

        • 具体描述:XPath的具体应用,如何锁定具体的元素路径。
      • 【已解决】-直接爬取在职级这一异步加载链接时,出现如下错误提示:

        • {"httpCode":403,"faultUid":"WebContainer : dggmwc5app355-Anonymous-9-9-48-30-508-2109","code":"huawei.jalor5.security.00010002","message":"您当前未登录。","entity":null,"stackTrace":""}

        • 解决方式:尝试更换网址链接,从主页进入。

    你可能感兴趣的:(【项目开发日志记录】-J项目-V2-已完成)