记一次Selenium框架的爬虫遇到下拉框页面的解决经历
背景
最近有一個項目需要使用爬蟲從某網站抓取全國的醫院名稱,等級,地址等信息
爬取的url為https://some/website/that/i/can/tell/you/sorry
用瀏覽器打開這個url會發現,切換不同的省市需要點擊左上角的下拉框進行選擇
問題
通常遇到這種下拉框頁面,我們第一時間想到使用Selenium框架的Select類,這個類是Selenium框架專門用于處理頁面下拉框的,使用方式如下:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.select import Selectdriver=webdriver.Chrome() #初始化瀏覽器驅動url='https://some/website/that/i/can/tell/you/sorry'#頁面url driver.get(url)#訪問相對應鏈接 windows_start=driver.window_handles[0] #文檔列表窗口名#定位省市 ele=driver.find_element(By.XPATH,'//*[@id="Prov"]') select_ele = Select(ele) select_ele.select_by_visible_text("北京市") time.sleep(1)#輸入醫院名稱 driver.find_element(By.XPATH,'//*[@id="Unit_Name"]').send_keys('協和醫院')但是Select類只能用于下拉框實現方式是基于html的select標簽的情況,針對本項目,打開頁面源碼發現
該頁面的下拉框使用的是input標簽!!!!
不慌!
既然不能用Select類一步到位,那我們就老老實實的模擬鼠標點擊等操作來實現爬取頁面過程的省市切換,找到Xpath,調用click()方法,簡直不要太簡單,呵呵呵
但是:
報錯信息no such element,意思是說找不到這個元素
經過不斷的排查發現這么一個現象:
第一次打開的時候下拉框的Xpath:
//*[@id="cascader-menu-7056-0-0"]/span/div
第二次打開的時候下拉框的Xpath:
//*[@id="cascader-menu-3644-0-0"]/span/div
下拉框的Xpath每次打開頁面是變化著的,也就是說開發這個頁面的前端工程師還是做了一點反爬措施的,每次點開頁面以后下拉框的id可能是隨機生成的,這可如何是好?
不慌!
解決思路
既然每次打開頁面的時候Xpath是變化著的,主要是Xpath中間有個四位數的隨機數
第一次打開的時候下拉框的Xpath:
//*[@id="cascader-menu-7056-0-0"]/span/div
第二次打開的時候下拉框的Xpath:
//*[@id="cascader-menu-3644-0-0"]/span/div
我們不去管隨機數,只關心當前頁面,想辦法拿到當前頁面的源碼,再從中解析出下拉框的Xpath,在模
擬點擊,則問題就迎刃而解!
基于這個思路,我們不必關心每次生成的隨機數具體是什么,早知道它是四位數,而且前面為//*[@id="cascader-menu-,后面為-0-0"]/span/div,那么使用正則表達式來解析簡直不要太簡單!
正則表達式如下:
#獲取隨機的ID bs = BeautifulSoup(driver.page_source, "html.parser") #解析頁面源碼 xpath_id = re.findall(r'cascader-menu-[0-9]+-[0-9].*city-select-component-span',driver.page_source)[0] xpath_id = re.findall(r'cascader-menu-[0-9]+-[0-9]+', xpath_id)[0]xpath_id = re.findall(r'\d+', xpath_id)[0]完整代碼
def change_province(driver, province_id):"""點擊下拉框切換特定省市"""#點擊下拉框driver.find_element(By.XPATH,'//*[@id="app_main"]/div/form/div[1]/div/div/div/input').click()time.sleep(1)#獲取隨機的IDbs = BeautifulSoup(driver.page_source, "html.parser")xpath_id = re.findall(r'cascader-menu-[0-9]+-[0-9].*city-select-component-span',driver.page_source)[0]xpath_id = re.findall(r'cascader-menu-[0-9]+-[0-9]+', xpath_id)[0]xpath_id = re.findall(r'\d+', xpath_id)[0]# 點擊切換固定id的省市driver.find_element(By.XPATH, '//*[@id="cascader-menu-{0}-0-{1}"]/span/div'.format(xpath_id, province_id)).click()time.sleep(np.random.randint(1, 3))def next_page(driver):"""點擊切換下一頁"""driver.find_element(By.XPATH,'//*[@id="app_main"]/div/div[2]/div/button[2]/i').click()time.sleep(np.random.randint(1,3))def get_info(driver):"""解析信息"""info_list=[]for i in range(1,11):try:info=driver.find_element(By.XPATH,'//*[@id="app_main"]/div/section/div[2]/div[3]/table/tbody/tr[{}]'.format(i)).text info=info.split('\n')info_list.append(info)except Exception as e:breakreturn info_listdriver=webdriver.Chrome() ocr = ddddocr.DdddOcr()url='https://some/website/that/i/can/tell/you/sorry'#打開url driver.get(url)#訪問相對應鏈接 windows_start=driver.window_handles[0] #文檔列表窗口名for province_id in range(0,32):change_province(driver,province_id) #順序切換省市max_page=driver.find_element(By.XPATH,'//*[@id="app_main"]/div/div[2]/div/ul/li[6]').text #獲取最大頁數max_page=int(max_page) data=get_info(driver) #獲取第一頁的數據for i in range(0,max_page-1):next_page(driver)data_1=get_info(driver)data.extend(data_1)df_temp=pd.DataFrame(data,columns=['序號','醫療機構名稱','醫療機構類型','醫療機構等級','詳細地址','開通情況'])df_temp.to_excel("./{}.xlsx".format(province_id))總結
以上是生活随笔為你收集整理的记一次Selenium框架的爬虫遇到下拉框页面的解决经历的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入理解Nginx:java业务逻辑层都
- 下一篇: Word如何设置单元格垂直居中