动态网页爬虫-智联招聘
Posted 柴立不阿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态网页爬虫-智联招聘相关的知识,希望对你有一定的参考价值。
▼
1"""
2@version: python3.6
3@author: ‘achai‘
4@software: PyCharm
5@file: zhilian_1.py
6@time: 2021/1/7 10:51
7
8"""
9from selenium.webdriver.common.keys import Keys
10from selenium import webdriver
11import time
12import re
13import xlwt
14book = xlwt.Workbook(encoding='utf-8', style_compression=0)
15sheet = book.add_sheet('job')
16sheet.write(0, 0, '岗位名称')
17sheet.write(0, 1, '薪资待遇')
18sheet.write(0, 2, '岗位描述')
19sheet.write(0, 3, '百度经度')
20sheet.write(0, 4, '百度纬度')
21n = 1
22def city(url):
23 # 实例化一个chrome对象 声明浏览器对象
24 browser = webdriver.Chrome()
25 # 浏览窗口最大化
26 browser.maximize_window()
27 browser.get(url)
28 # 登录
29 browser.find_element_by_xpath('//*[@id="zpPassportWidget"]/div/div/div/div/div[1]/div/div').click()
30 # 获取当前窗口handle name
31 current_window_0 = browser.current_window_handle
32 time.sleep(1)
33 browser.find_element_by_xpath('//*[@id="zpPassportWidget"]/div/div/div/div/div[2]/ul/li[2]').click()
34 # 手动登录
35 time.sleep(10)
36 # 自动登录
37 browser.find_element_by_xpath('//*[@id="zpPassportWidget"]/div/div/div/div/div[2]/div/div[1]/div/p_submit/div/button').click()
38 # 手动解决滑块
39 time.sleep(10)
40 # 获取当前窗口handle name
41 current_window_0 = browser.current_window_handle
42 # 切换城市:石家庄
43 browser.find_element_by_xpath('//*[@id="rightNav_top"]/div/div[1]/div/div[1]/div/a').click()
44 # 等待搜索后的内容
45 time.sleep(1)
46 # 返回当前会话中所有窗口的句柄
47 all_window_1 = browser.window_handles # 返回当前会话中所有窗口的句柄。
48 # print("all_window:: ",all_window) # 打印当前所有窗口的句柄 name
49 # 通过遍历判断要切换的窗口
50 for window in all_window_1:
51 # print("window: ", window)
52 if window != current_window_0:
53 browser.switch_to.window(window) # 将定位焦点切换到指定的窗口,包含所有可切换焦点的选项
54 current_window_1 = browser.current_window_handle # 获取当前窗口handle name
55 # print("current_window(1): ", current_window_1) # 打印当前窗口的句柄 name
56 time.sleep(1)
57 # 将页面滚动条拖到底部
58 js = "var q=document.documentElement.scrollTop=100000"
59 # 定位‘S’
60 browser.execute_script(js)
61 # 定位石家庄
62 browser.find_element_by_xpath('//*[@id="root"]/div[2]/div[2]/div/div[2]/ul/li[17]/a').click()
63 # 注意!!必须要休眠!!!
64 time.sleep(1)
65 browser.find_element_by_xpath('//*[@id="root"]/div[2]/div[3]/div[17]/ul/li[4]/a').click()
66 all_window_2 = browser.window_handles
67 for windoww in all_window_2:
68 # print("window: ", windoww)
69 if windoww != current_window_1:
70 browser.switch_to.window(windoww) # 将定位焦点切换到指定的窗口,包含所有可切换焦点的选项
71 current_window_2 = browser.current_window_handle # 获取当前窗口handle name
72 # print("current_window(2): ", current_window_2) # 打印当前窗口的句柄 name
73 time.sleep(1)
74 # 拖动页面滚动条,定位到全部职位
75 js = "var q=document.documentElement.scrollTop=100"
76 browser.execute_script(js)
77 # 跳转至全部职位
78 browser.find_element_by_xpath('//*[@id="root"]/div[3]/div/div[1]/ol/li[9]/a').click()
79 all_window_4 = browser.window_handles # 返回当前会话中所有窗口的句柄。
80 for windowwww in all_window_4:
81 # print("window: ", windowwww)
82 if windowwww != current_window_2:
83 browser.switch_to.window(windowwww) # 将定位焦点切换到指定的窗口,包含所有可切换焦点的选项
84 current_window_4 = browser.current_window_handle # 获取当前窗口handle name
85 # print("current_window(4): ", current_window_4) # 打印当前窗口的句柄 name
86 time.sleep(1)
87
88 # 重新定位城市
89 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div[1]/div[1]/a').click()
90 time.sleep(1)
91 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div[2]/div[2]/input').send_keys('石家庄')
92 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div[2]/div[2]/input').send_keys(Keys.ENTER)
93 time.sleep(1)
94
95 item = {} # 初始化一个字典, 用来存放城区链接
96 # 定位行政区
97 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div/div[2]/a').click()
98 # 定位石家庄市新华区
99 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div[2]/div/ul/li[15]/a').click()
100 # 获取新华区的url
101 item['新华区'] = browser.current_url
102
103 # 取消选中新华区
104 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div/div[2]/a[1]').click()
105 # 定位石家庄市长安区
106 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div[2]/div/ul/li[21]/a').click()
107 # 获取长安区的url
108 item['长安区'] = browser.current_url
109
110 # 取消选中长安区
111 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div/div[2]/a[1]').click()
112 # 定位石家庄市桥西区
113 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div[2]/div/ul/li[11]/a').click()
114 # 获取桥西区的url
115 item['桥西区'] = browser.current_url
116
117 # 取消选中桥西区
118 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div/div[2]/a[1]').click()
119 # 定位石家庄市裕华区
120 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div[2]/div/ul/li[19]/a').click()
121 # 获取裕华区的url
122 item['裕华区'] = browser.current_url
123
124 # 取消选中裕华区
125 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div/div[2]/a[1]').click()
126 # 定位石家庄市东开发区
127 browser.find_element_by_xpath('//*[@id="filter-hook"]/div/div[2]/div[2]/div/ul/li[1]/a').click()
128 # 获取东开发区的url
129 item['东开发区'] = browser.current_url
130
131 # print(item)
132 # 新华区的url: https://sou.zhaopin.com/?jl=565&re=2291&p=1
133 # 长安区的url: https://sou.zhaopin.com/?jl=565&re=2288&p=1
134 # 桥西区的url: https://sou.zhaopin.com/?jl=565&re=2290&p=1
135 # 裕华区的url: https://sou.zhaopin.com/?jl=565&re=2292&p=1
136 # 东开发区的url: https://sou.zhaopin.com/?jl=565&re=2293&p=1
137
138 lists = []
139 for key, value in item.items():
140 # print(key + ": " + str(value))
141 print('正在获取' + key + '岗位链接')
142 # 获取智联招聘总页码
143 for page in range(1, 2):
144 browser.get(str(value)[:-1] + f'{page}') # 以 f开头表示在字符串内支持大括号内的python 表达式
145 # xpath定位包含职位链接的class
146 for i in range(1, 31):
147 job_ls = browser.find_elements_by_xpath('//*[@id="positionList-hook"]/div/div[' + str(i) + ']/a')
148 # 遍历职位链接
149 # lists = []
150 # x = 0
151 for j in job_ls:
152 results = j.get_attribute("href") # 打印遍历标签出来的内容和获取href属性的内容
153 lists.append(results)
154 # x = x + 1
155 # print('正在获取第' + str(x) + '条岗位链接')
156 #关闭当前浏览器对象
157 browser.quit()
158 time.sleep(2)
159 return lists
160
161def getJob(results):
162 # 自动登录
163 # options = webdriver.ChromeOptions()
164 # options.add_argument('--proxy-server=127.0.0.1:8080') # 以8080端口启动谷歌浏览器
165 # options.add_argument('--ignore-certificate-errors') # 忽略证书错误
166 # options.add_argument(r"user-data-dir=C:\Users\11755\AppData\Local\Google\Chrome\User Data") # 指定用户文件夹
167 # options.add_experimental_option("excludeSwitches", ["enable-automation"])
168 # options.add_experimental_option('useAutomationExtension', False)
169 # driver = webdriver.Chrome(options=options)
170 # driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
171 # "source": """
172 # Object.defineProperty(navigator, 'webdriver', {
173 # get: () => undefined
174 # })
175 # """
176 # })
177 try:
178 # 无头浏览器免登录获取信息
179 chrome_options = webdriver.ChromeOptions()
180 chrome_options.add_argument('--headless')
181 chrome_options.add_argument('--disable-gpu')
182 driver = webdriver.Chrome(chrome_options=chrome_options)
183 driver.set_page_load_timeout(30)
184 driver.maximize_window()
185
186 i = 0
187 for url in results:
188 driver.get(str(url))
189 # 岗位名称
190 name = driver.find_element_by_class_name("summary-plane__title").text
191 print(name)
192 # 薪资
193 money = driver.find_element_by_class_name("summary-plane__salary").text
194 print(money)
195
196 # 岗位描述
197 text = driver.find_element_by_class_name("describtion__detail-content").text
198 print(text)
199
200 # r的作用是忽略转义字符 findall查找符合要求的字符串,以列表的形式输出
201 # 经度
202 longitude = re.findall(r'longitude.*?([1-9]\d*\.?\d*)', driver.page_source,
203 re.M) # 以指定字符串“latitude”开头,以“,”结尾
204 print(longitude)
205 # 纬度
206 latitude = re.findall(r'latitude.*?([1-9]\d*\.?\d*)', driver.page_source, re.M)
207 print(latitude)
208
209 i = i + 1
210 print('已完成第' + str(i) + '条岗位信息提取')
211 time.sleep(1)
212
213 if len(name):
214 global n
215 sheet.write(n, 0, name)
216 sheet.write(n, 1, money)
217 sheet.write(n, 2, text)
218 sheet.write(n, 3, longitude)
219 sheet.write(n, 4, latitude)
220
221 n = n + 1
222 book.save('ZhiLian_sjz.xls')
223
224 except:
225 print("信息获取失败")
226 time.sleep(3) # 30秒后执行程序
227
228if __name__ == '__main__':
229 url = 'https://www.zhaopin.com/'
230 results = city(url) #变量urban_area_url接收字典返回值
231 getJob(results)
问题1:网页操作没有反应
解决:通常我们selenium元素的时间经常遇到只要跳转页面了,定位就总是找不到我要找的元素,这是因为的你定位指针driver没有指向第二个页面,所以无法定位。
问题2:查找元素
方法:通过三种不同的方式去获取响应的元素,第一种是通过id的方式,第二个中是CSS选择器,第三种是xpath选择器,结果都是相同的:
input_first = browser.find_element_by_id("q")
input_second = browser.find_element_by_css_selector("#q")
input_third =browser.find_element_by_xpath('//*[@id="q"]')
问题3:智联招聘账密为动态ID
解决:根据相对关系定位,通过父节点定位子节点,也或者手动方式呢
问题4:webdriver中的等待
方法:强制等待:sleep()
设置固定休眠时间,单位为秒。由python的time包提供, 导入 time 包后就可以使用。
缺点:不智能,使用太多的sleep会影响脚本运行速度。
隐式等待:implicitly_wait()
driver.implicitly_wait(10) #隐式等待10秒
使用隐式等待的时候,会不断轮询去寻找所定位的元素(轮询频率的时间默认是0),找到了就立即继续执行后面的代码,找不到,将继续等待,直到超出设定时间后则抛出找不到元素的异常
显示等待:WebDriverWait()
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
driver:浏览器驱动
timeout:最长超时时间,默认以秒为单位
poll_frequency:检测的间隔步长,默认为0.5s
ignored_exceptions:超时后的抛出的异常信息,默认抛出NoSuchElementExeception异常。
问题5:重复登录问题
方法:Cookie,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓取某个页面内容是不允许的。那么我们可以利用 Urllib2 库保存我们登录的 Cookie,然后再抓取其他页面就达到目的了。
注意:加载cookies之前需要先访问一下页面。
参考:关于selenium获取cookie然后实现免登录_可大侠的博客-CSDN博客_selenium获取cookie
问题6:滑动滑块后报错
方法:爬取某个网站的时候,拖动完滑块以后,系统并未显示出正常滑动完滑块的页面,而是报了一个错误,这代表爬虫系统被检测出来非人为操作
参考:
以上是关于动态网页爬虫-智联招聘的主要内容,如果未能解决你的问题,请参考以下文章
携程智联等网站百分之60%的访问量都是爬虫,对此我们应该怎么办