说明:
本文仅用于selenium相关语法的学习,如有任何问题,欢迎大家批评指正~~
crawl数据保存到csv文件:
- 这个是不含job详细信息的【即爬取过程中不涉及页面切换】
- 这个是包含job详细信息的【代码比上边稍微复杂一点,涉及到页面切换】
代码实现【含页面切换】:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time
import pandas as pd
from selenium.webdriver.common.keys import Keys
class QCWY:
def __init__(self, keyword, city, maxpagenum): #构造函数
self.keyword = keyword
self.city = city
self.maxpagenum = maxpagenum
def run(self): #执行爬虫任务的函数
options = webdriver.ChromeOptions()
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(service=Service(r'E:\Chrome Download\chromedriver_win32\chromedriver.exe'), options=options)
driver.implicitly_wait(10)
driver.get("https://www.51job.com/")
#输入关键字
driver.find_element(By.ID, "kwdselectid").send_keys(self.keyword)
#点击选择城市
driver.find_element(By.ID, "work_position_input").click()
#等待一秒,确保界面稳定
time.sleep(1)
#选择城市,点击上方当前已经选中的城市,去掉这些
selectedCityEles = driver.find_elements(By.CSS_SELECTOR, "#work_position_click_multiple_selected > span")
#挨个点掉
for one in selectedCityEles:
one.click()
#拿到下边所有的热门城市
cityEles = driver.find_elements(By.CSS_SELECTOR, "#work_position_click_center_right_list_000000 em")
#在热门城市中找一下我们想要选择的那个城市
target = None #用来标记是否找到,如果找到就存下来
for cityEle in cityEles:
if cityEle.text == self.city:
target = cityEle
break
#如果底下热门城市没有我们想要的
if target is None:
input(f'{self.city} 不在热门城市列表中,请自己手动在左侧按字母查找到城市【按回车程序可继续运行】')
else:
target.click() #点击一下这个热门城市
#保存城市选择,点击下方的确定
driver.find_element(By.ID, "work_position_click_bottom_save").click()
#点击搜索按钮
driver.find_element(By.CSS_SELECTOR, 'div.ush > button').click()
#创建dataframe,最后存到csv文件中
df = pd.DataFrame(data=None, columns=['职位名称', '薪资-地点-学历', '企业名称', '企业经营情况', '企业服务类型', '职位详细信息'])
#遍历每一页
for pageNo in range(1, self.maxpagenum+1):
#设置页码
pageNoInput = driver.find_element(By.ID, 'jump_page')
# pageNoInput.clear() #这样清除不掉
pageNoInput.send_keys(Keys.CONTROL, 'a') #全选
pageNoInput.send_keys(str(pageNo))
driver.find_element(By.CLASS_NAME, 'jumpPage').click()
#停留1s,等页面出来
time.sleep(1)
#爬取这页的数据
currPageJobsList = self.handleOnePage(driver)
for job in currPageJobsList:
df = df.append(job, ignore_index=True)
#判断这页是否是最后一页了,避免我们设置的最大页数超过网站提供的页数
if self.isLastPage(driver):
break
df.to_csv(r'51job.csv', index=False, encoding='utf_8_sig')
def isLastPage(self, driver):
# 注意这里一定要用find_elements,因为即使找不到这个元素,返回的是空列表,也不会报错使程序终止
nextPageButton = driver.find_elements(By.CSS_SELECTOR, 'button[disabled=disabled].btn-next')
if nextPageButton: #列表不为空,找到了末尾页的标识,那这就是最后一页
return True
else: #列表为空
return False
def handleOnePage(self, driver):
currPagejobList = []
# 拿到这页上的所有工作岗位招聘条目区域
jobs = driver.find_elements(By.CSS_SELECTOR, ".j_joblist div.e")
# print(len(jobs))
#对这页的处理
selector = "a span.jname , a p.info , div.er .cname , div.er .dc , div.er .int"
for job in jobs: # 遍历这页上的每条工作
fields = job.find_elements(By.CSS_SELECTOR, selector)
stringFields = [field.text for field in fields]
# print(stringFields)
dict = {
'职位名称': stringFields[0],
'薪资-地点-学历': stringFields[1],
'企业名称': stringFields[2],
'企业经营情况': stringFields[3],
'企业服务类型': stringFields[4]
}
#让页面跳转,去爬取职位的详细信息
# fields[0].click() #直接点它会报错,因为页面下拉时上边会有一个悬浮窗,挡住了我们根本点不了
driver.execute_script('arguments[0].click()', fields[0]) #直接使用js脚本来点击,参考链接:http://t.csdn.cn/8kiCg
mainWindow = driver.current_window_handle #保存一下当前主窗口,最后还要跳转回来
driver.switch_to.window(driver.window_handles[-1]) #浏览器中最后打开的窗口
#跳转到新的页面,需要访问验证,解决方案参考博客:http://t.csdn.cn/aNQRg
info = driver.find_elements(By.CLASS_NAME, 'job_msg')
driver.implicitly_wait(1)
if info and len(info)==1: #列表不为空
dict['职位详细信息'] = info[0].text
print(info[0].text)
#这条job的字典构造好啦,追加保存一下吧
currPagejobList.append(dict)
#关闭职位信息页(因为打开窗口太多损耗性能)
driver.close()
#切换回主窗口
driver.switch_to.window(mainWindow)
return currPagejobList
QCWY(keyword='python', city='上海', maxpagenum=2).run() #创建实例并调用run方法