美文网首页
【项目开发日志记录】-J项目-V2-已完成

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

作者: 布衣夜行人 | 来源:发表于2022-01-19 19:09 被阅读0次

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

用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 <a target="_blank" class="recommond_link hrefItem textoverflow" href="hometalent_full.html#!hometalent/portal/jobView.html?jobId=207114&amp;types=1" title="MBB (移动宽带)GTM">...</a> is not clickable at point (168, 10). Other element would receive the click: <li class="tab_home active" tab="tab_home">...</li>
 (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
  • 目标网站及基本特征数据

    • 主页网址:http://w3.huawei.com/ihrm/hometalent_index.html

    • 刚进入主页后的输入框勾选:<input type="checkbox" id="poolSelectCheckTips" onclick="btnCheck()">

    • 勾选输入框之后的确认键:<span class="btn_close btn_close_select" id="btnconfirm" onclick="btnconfirmCloseFun()">确定</span>

    • 职位信息是在<div class="centent_l fl"> <h3> <a target="_blank" class="recommond_link hrefItem textoverflow" href="hometalent_full.html#!hometalent/portal/jobView.html?jobId=166350&types=1" title="产品营销经理-平板与PC(笔记本、平板/选件、台式机/软件)-Global MKT">产品营销经理-平板与PC(笔记本、平板/选件、台式机/软件)-Global MKT </a> </h3> <p class="textoverflow" style="width:280px;display:inline-block">14-18 </p> <div class="introduction defaultColor textoverflow">营销族/消费者整合营销类/消费者整合营销 </div> </div>

    • //*[@id="postCentent"]/div[1]/div[1]/h3/a

    • <a target="_blank" class="recommond_link hrefItem textoverflow" href="hometalent_full.html#!hometalent/portal/jobView.html?jobId=172418&types=1" title="高级营销经理-马来西亚">高级营销经理-马来西亚 </a>

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

  • 尝试获取日志

    • 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-已完成

      本文链接:https://www.haomeiwen.com/subject/wzbfhrtx.html