用到的知識點:
- selenium 顯式等待
- 兩個窗口的切換
'''用selenium爬取拉勾'''
from lxml import etree
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
import xlrd,xlwt,re,codecs,time
class LagouSpider():
def __init__(self):
self.url = 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput='
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser,10)
def run(self):
self.browser.get(self.url)
while True:
text = self.browser.page_source
# 提取具體頁面的url
self.parse_page(text)
# 提取下一頁的按鈕,注意class的值中有空格不可用。
next_btn = self.wait.until(EC.presence_of_element_located((By.XPATH,'//div[@class="pager_container"]/span[last()]')))
# 判斷是否是最后一頁,如果是,退出while循環(huán)
if 'pager_next pager_next_disabled' in next_btn.get_attribute('class'):
break
else:
next_btn.click()
time.sleep(1)
# 提取具體頁面的url
def parse_page(self,text):
html = etree.HTML(text)
# 判斷所需元素是否加載出來
self.wait.until(EC.presence_of_element_located((By.XPATH,'//a[@class="position_link"]')))
detial_urls = html.xpath('//a[@class="position_link"]/@href')
for detial_url in detial_urls:
# 請求詳情頁
self.request_detial_url(detial_url)
time.sleep(1)
# 提取之后,把當(dāng)前的頁面關(guān)閉
# 請求詳情頁
def request_detial_url(self,detial_url):
# 解析具體頁面的字段信息時候,打開了另一個頁面,覆蓋原來的頁面,我們這里做的是利用while True循環(huán)來獲取全部頁面的字段信息
# 所以第一個頁面的窗口不能關(guān)閉
self.browser.execute_script("window.open('%s')" % detial_url) # 打開另一個窗口
self.browser.switch_to.window(self.browser.window_handles[1]) # 切換到另一個窗口
source = self.browser.page_source
# 解析詳情頁的具體字段
self.parse_detial_url(source)
# 請求完之后關(guān)閉當(dāng)前詳情頁的頁面
self.browser.close()
# 切換回第一頁
self.browser.switch_to.window(self.browser.window_handles[0]) # 切換到首頁
# 解析詳情頁的具體字段
def parse_detial_url(self,source):
text = etree.HTML(source)
# 判斷所需元素是否加載出來
self.wait.until(EC.presence_of_element_located((By.XPATH,'//span[@class="name"]')))
name = text.xpath('//span[@class="name"]/text()')[0]
salsry = text.xpath('//dd[@class="job_request"]/p[1]/span[1]/text()')[0].strip()
city = text.xpath('//dd[@class="job_request"]/p[1]/span[2]/text()')[0]
city = re.sub(r'[\s/]', '', city)
work_years = text.xpath('//dd[@class="job_request"]/p[1]/span[3]/text()')[0]
work_years = re.sub(r'[\s/]', '', work_years)
job_advantage = text.xpath('//dd[@class="job-advantage"]/p/text()')[0]
desc = ''.join(text.xpath('//dd[@class="job_bt"]//text()')).strip()
print(name,salsry,city,work_years,job_advantage)
output = ('{}\t{}\t{}\t{}\t{}\n').format(name, salsry,city,work_years,job_advantage)
f = codecs.open('lagou.xls', 'a+')
f.write(output)
f.close()
def main():
spider = LagouSpider()
spider.run()
if __name__ == '__main__':
main()