項目開發(fā)過程中的知識點收獲
用csv文件存儲數(shù)據(jù)時彬坏,同步自定義設(shè)置表頭的代碼實現(xiàn)
要點:在寫入csv文件時,設(shè)置參數(shù)header烤芦。寫入順序即為自身設(shè)置的順序
form_header = ['職位名稱','職級','職位族']
數(shù)據(jù) = pd.DataFrame({'職位名稱':job_name_list,'職級':job_level_list,'職位族':job_family_list})
數(shù)據(jù).to_csv('d:/職位信息.csv',mode='a',header=form_header,encoding='ANSI')
DataFrame中的字典結(jié)構(gòu)數(shù)據(jù)胁编,鍵名后面的值的數(shù)據(jù)類型必須是列表的類型呻惕。
數(shù)據(jù) = pd.DataFrame({'職位名稱':job_name_list,'職級':job_level_list,'職位
函數(shù)調(diào)用報錯-name 'children_page' is not define
解決方式:把自己定義寫好的函數(shù)放在主函數(shù)的最前面酷鸦。因為程序編譯器的解析饰躲,是從上到下進(jìn)行編譯執(zhí)行的。上述錯誤即是因為函數(shù)沒有定義的問題臼隔。
子頁面鏈接點擊爬取問題
browser = webdriver.Chrome()
browser=job_name.click()
print(browser)
在子函數(shù)中嘹裂,嘗試新建瀏覽器對象來進(jìn)行詳情頁面的關(guān)鍵信息抓取,但點擊列表頁超鏈接后摔握,并未有接收到任何返回值寄狼。
子頁面鏈接點擊爬取后的返回值問題
現(xiàn)象:返回值必須含有瀏覽器對象,否則在下一次運行函數(shù)氨淌,會出現(xiàn)如下報錯;
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 瀏覽器對象
函數(shù)返回值如果有多個泊愧,其實返回的是元組。Python的函數(shù)返回多值其實就是返回一個tuple盛正,但寫起來更方便拼卵。
函數(shù)返回多個值,只取部分值
一個常見的慣例是使用“_“作為要忽略的元組元素的變量名蛮艰。例如:
def f():
return 1, 2, 3
_, _, x = f()
異常問題:下拉加載多項之后,點擊詳細(xì)頁的加載方式失效
具體報錯代碼如下:
ElementClickInterceptedException: element click intercepted: Element <a target="_blank" class="recommond_link hrefItem textoverflow" href="hometalent_full.html#!hometalent/portal/jobView.html?jobId=207114&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 # 動作鏈
#定義抓取詳情頁的函數(shù)-直接點擊子頁面爬取的方式
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
#主程序
網(wǎng)址 = '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()
# 使用瀏覽器打開網(wǎng)址
瀏覽器對象.get(網(wǎng)址)
#因為網(wǎng)絡(luò)存在延遲雀彼,所以需要延緩幾秒打開網(wǎng)頁壤蚜,否則可能存在元素未完全加載的情況
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')
#實測發(fā)現(xiàn)先點擊職位族,再點擊職級抓取的數(shù)據(jù)相對會更準(zhǔn)確一些徊哑。兩者順序調(diào)換后袜刷,抓取的數(shù)據(jù)中前面幾個會有技術(shù)族的信息。
#篩選條件點擊-職位族
瀏覽器對象.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秒莺丑,等待數(shù)據(jù)加載
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'])
#將列表字典中的數(shù)據(jù)進(jìn)行提取著蟹,準(zhǔn)備文件儲存
print(goal_job_name_list)
print(goal_work_place_list)
數(shù)據(jù) = pd.DataFrame({'職位名稱':goal_job_name_list,'工作地':goal_work_place_list,'發(fā)布時間':goal_update_list,'崗位部門':goal_department_list,'職位族':goal_job_family_list,'職級':goal_job_level_list,'崗位職責(zé)':goal_job_duty_list,'任職要求':goal_job_request_list,})
數(shù)據(jù).to_excel('d:/job_information.xlsx')
#數(shù)據(jù).to_csv('d:/職位信息.csv',mode='a',header=form_header,encoding='ANSI')
附錄-網(wǎng)頁加載過程中的一些邏輯分析(已無太大意義)
項目開發(fā)-inner
-
目標(biāo)網(wǎng)站及基本特征數(shù)據(jù)
剛進(jìn)入主頁后的輸入框勾選:<input type="checkbox" id="poolSelectCheckTips" onclick="btnCheck()">
勾選輸入框之后的確認(rèn)鍵:<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="產(chǎn)品營銷經(jīng)理-平板與PC(筆記本墩蔓、平板/選件、臺式機(jī)/軟件)-Global MKT">產(chǎn)品營銷經(jīng)理-平板與PC(筆記本萧豆、平板/選件奸披、臺式機(jī)/軟件)-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="高級營銷經(jīng)理-馬來西亞">高級營銷經(jīng)理-馬來西亞 </a>
-
網(wǎng)站特點及加載邏輯分析
剛剛進(jìn)入網(wǎng)站時,會發(fā)生鏈接的重定向跳轉(zhuǎn)涮雷。彈出一個框框讓勾選阵面,比較討厭
網(wǎng)頁是屬于Ajax異步加載的,通過下拉加載更多洪鸭,會發(fā)送Ajax請求样刷。
點擊職級時,出現(xiàn)的異步加載鏈接:http://w3.huawei.com/ihrm/services/hometalent/portal/newPortal/findAllJobForPortal/10/1?jobLevel=13%2C14&orderBy=LAST_UPDATE_DATE_DESC&someondeCount=17
點擊職位族時览爵,出現(xiàn)的異步加載鏈接:http://w3.huawei.com/ihrm/services/hometalent/portal/newPortal/findAllJobForPortal/10/1?jobFamily=J19&orderBy=LAST_UPDATE_DATE_DESC&someondeCount=19
【規(guī)律發(fā)現(xiàn)】:在這個Ajax請求里有發(fā)現(xiàn)置鼻,職級為obLevel=13%2C14這種,職位族為jobFamily
-
嘗試獲取日志
-
2022/1/10-利用XPath獲取數(shù)據(jù)當(dāng)前存在問題
- 具體描述:XPath的具體應(yīng)用蜓竹,如何鎖定具體的元素路徑箕母。
-
【已解決】-直接爬取在職級這一異步加載鏈接時,出現(xiàn)如下錯誤提示:
{"httpCode":403,"faultUid":"WebContainer : dggmwc5app355-Anonymous-9-9-48-30-508-2109","code":"huawei.jalor5.security.00010002","message":"您當(dāng)前未登錄梅肤。","entity":null,"stackTrace":""}
解決方式:嘗試更換網(wǎng)址鏈接司蔬,從主頁進(jìn)入。
-