您好,登錄后才能下訂單哦!
這篇文章給大家分享的是用selenium工具抓取網站數據的方法,相信大部分人都還沒學會這個技能,為了讓大家學會,給大家總結了以下內容,話不多說,一起往下看吧。
用到的主要工具:
python3.5
selenium
scrapy
由于[網站的數據跟單(http://www.gendan5.com/tech.html)是可以按照地市來查詢的,所以先訪問該網站支持的城市劃分
使用scrapy的self.start_urls進行請求
self.start_urls = ['https://www.zhipin.com/wapi/zpCommon/data/city.json',]
1
同時使用selenium請求該網站主頁
self.driver.get('https://www.zhipin.com/')
1
后來發現網站可以識別selenium,不返回數據,于是添加
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-automation'])
self.driver = webdriver.Chrome(options=options)
將程序設置為開發者模式,數據可以正常請求到
接下來就是解析支持搜索的城市名,并且匯總成我們能使用的數據格式
dic = {}
json_text = json.loads(response.text)['zpData']['cityList']
for i in range(len(json_text)):
# 獲取到各個省的名稱,并且作為字典的鍵名賦值
province = json_text[i]['name']
provinces = json_text[i]['subLevelModelList']
dic.setdefault(province,[])
citys = []
# 分類直轄市和地級市,并歸類到字典的值
if provinces.__len__() > 1:
for ii in range(len(provinces)):
city = provinces[ii]['name']
citys.append(city)
else:
city = province
citys.append(city)
dic[province] = citys
準備工作完成了,接下來就是請求數據了
self.driver.find_element_by_xpath('//*[@id="wrap"]/div[3]/div/div/div[1]/form/div[2]/p/input').send_keys('需要查詢的崗位') # 主頁搜索框,過度用
sleep(2)
self.driver.find_element_by_xpath('//*[@id="wrap"]/div[3]/div/div/div[1]/form/button').click()
sleep(2)
到這里,程序算是進入了正軌,直接貼上代碼。如下:
import scrapy
import json
import re
from scrapy.spiders import CrawlSpider
from time import sleep
from ..items import ZhaopinBossZhipinItem
from scrapy.selector import Selector
import importlib
import random
from selenium import webdriver
import sys
importlib.reload(sys)
class ZP_boss(CrawlSpider):
name = "boss"
custom_settings = {
'ITEM_PIPELINES': {'zhaopin_bosszhipin.pipelines.ZhaopinBossPipeline': 300, },
'scrapy.downloadermiddlewares.cookies.CookiesMiddleware': 1,
'DOWNLOAD_DELAY': 0.5,
'MYEXT_ENABLED': True
}
def __init__(self,):
super(ZP_boss,self).__init__()
self.allowed_domains = ["https://www.baidu.com"] # 過濾的url
self.start_urls = ['https://www.zhipin.com/wapi/zpCommon/data/city.json',] # 訪問網頁支持搜索的城市
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-automation'])
self.driver = webdriver.Chrome(options=options)
self.driver.maximize_window() # 瀏覽器設置成頁面最大化
self.driver.get('https://www.zhipin.com/')
def parse(self, response):
dic = {}
json_text = json.loads(response.text)['zpData']['cityList']
for i in range(len(json_text)):
# 獲取到各個省的名稱,并且作為字典的鍵名賦值
province = json_text[i]['name']
provinces = json_text[i]['subLevelModelList']
dic.setdefault(province,[])
citys = []
# 分類直轄市和地級市,并歸類到字典的值
if provinces.__len__() > 1:
for ii in range(len(provinces)):
city = provinces[ii]['name']
citys.append(city)
else:
city = province
citys.append(city)
dic[province] = citys
self.driver.find_element_by_xpath('//*[@id="wrap"]/div[3]/div/div/div[1]/form/div[2]/p/input').send_keys('python') # 主頁搜索框,過度用
sleep(2)
self.driver.find_element_by_xpath('//*[@id="wrap"]/div[3]/div/div/div[1]/form/button').click()
sleep(2)
for prov in dic.keys(): # 循環抓取到的省名
cts = dic[prov] # 單個省或者直轄市包含的所有城市
for ct in cts: # 單個城市名
query = '搜索的崗位'+ct
self.driver.find_element_by_xpath('//p[@class="ipt-wrap"]/input[@name="query"]').clear()
# sleep(0.1)
self.driver.find_element_by_xpath('//p[@class="ipt-wrap"]/input[@name="query"]').send_keys(query)
sleep(0.2)
self.driver.find_element_by_xpath('//button[@class="btn btn-search"]').click() # 點擊查詢數據
sleep(1)
# source = Selector(text=self.driver.page_source)
panduan = True
while panduan: # 循環翻頁
sou = Selector(text=self.driver.page_source)
link_lens = sou.xpath('//*[@id="main"]/div/div[2]/ul/li').extract() # 獲取當前頁面所有的li標簽,一個標簽就是一條招聘數據
# 分解出當前頁面每一個li標簽,并獲取到部分數據
for link_text in link_lens:
sel = Selector(text=link_text)
# 招聘單位
company = ''.join(sel.xpath('//div[@class="company-text"]/h4/a/text()').extract()).strip()
# 城市
city = ct
# 學歷要求
education = ''.join(sel.xpath('//div[@class="info-primary"]/p/text()[3]').extract()).strip()
# 工作經驗
experience = ''.join(sel.xpath('//div[@class="info-primary"]/p/text()[2]').extract()).strip()
# 獲取數據的城市地址
adrs_text = sel.xpath('//p/text()').extract()
if adrs_text: # 加這個判斷是為了保證有城市數據,有時候網頁會抽風導致 下標越界或空對象沒有group()方法的錯
adrs = re.search('(\w+?)\s',''.join(adrs_text[0])).group().strip() # 匹配出當前招聘所在城市名
if adrs != ct: # 如果沒有匹配數據,網站會把該省的其他市數據返回,篩選掉這部分數據,只做精準匹配
panduan = False
continue
else:
pass
are = re.search('\s(\w+?)\s',''.join(adrs_text[0])) # 城市的區
if are:
area = are.group().strip()
else:
area = ''
main_url = 'https://www.zhipin.com'
link_href = ''.join(sel.xpath('//div[@class="info-primary"]/h4[@class="name"]/a/@href').extract()).strip()
url = main_url + link_href
# 獲取詳情頁的索引值
href_index = ''.join(sel.xpath('//div[@class="info-primary"]/h4[@class="name"]/a/@data-index').extract()).strip()
# 點擊進入詳情頁
link_page = self.driver.find_element_by_xpath('//div[@class="info-primary"]/h4/a[@data-index="{}"]/div[@class="job-title"]'.format(href_index))
link_page.click()
# driver切換到新頁面,獲取詳情頁數據
n = self.driver.window_handles # 獲取到所有窗口,返回的是一個list,下標從0開始
self.driver.switch_to.window(n[1]) # 切換到新的網頁窗口視圖,driver的page_source也會更改成新頁面的
sleep(1)
se = Selector(text=self.driver.page_source)
# 崗位
job_name = ''.join(se.xpath('//div[@class="name"]/h2/text()').extract()).strip()
# 薪資
salary = ''.join(se.xpath('//div[@class="name"]/span[@class="salary"]/text()').extract()).strip()
# 福利
welfare = ';'.join(se.xpath('//*[@id="main"]/div[1]/div/div/div[2]/div[3]/div[2]/span/text()').extract()).strip()
# 發布時間
publishtime = ''.join(re.findall('\d+.*',''.join(se.xpath('//*[@id="main"]/div[3]/div/div[1]/div[2]/p[@class="gray"]/text()').extract()))).strip()
# 崗位職責
Duty = ''.join(se.xpath('//*[@id="main"]/div[3]/div/div[2]/div[2]/div[1]/div[@class="text"]').extract()).strip()
# 詳細地址
address = ''.join(se.xpath('//*[@id="main"]/div[3]/div/div[2]/div[2]/div/div[@class="job-location"]/div[@class="location-address"]/text()').extract()).strip()
print('發布時間:',publishtime)
print('崗位名稱:',job_name)
print('招聘單位:',company)
print('學歷要求:',education)
print('工作經驗:',experience)
print('薪資:',salary)
print('福利:',welfare)
print('地址:',address)
print('崗位職責:',Duty)
self.driver.close() # 必須關閉當前數據頁面,否則會占用大量資源,查詢數據量很大的時候會導致宕機。。。
sleep(0.5)
self.driver.switch_to.window (n[0]) # 切換回原網頁
else:
continue
# 先判斷是否有分頁信息,每頁最多30條數據(30個li標簽),少于30條數據表示沒有下一頁了
if link_lens.__len__() < 30:
print('沒有下一頁了')
panduan = False
else:
if panduan: # 會出現有下一頁但是數據不是我們查詢的市的數據,已在上方進行了判斷(if adrs != ct:)
if ''.join(sou.xpath('//a[@ka="page-next"]/@href').extract()) == "javascript:;": # 網站最多顯示10頁數據,不做判斷會導致死循環
panduan = False
else:
next_page = self.driver.find_element_by_xpath('//a[@ka="page-next"]') # 翻頁按鈕
next_page.click() # 點擊翻頁
print('準備抓取下一頁')
sleep(random.randint(1,5)) # 考慮到封ip,適當休眠
else:
break
sleep(random.randint(5,15))
self.driver.quit() # 程序運行結束,關閉瀏覽器進程
數據爬取完畢。
pipelines,sttings和item的代碼千篇一律,這里就不放上來了。
由于使用的是selenium,注定了爬取速度不會很快。
看完這篇文章,你們學會用selenium工具抓取網站數據的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。