一、分析页面
拿到页面不要慌,先分析出目标数据,在各省分数线一栏有年份、录取批次、招生类型、最低分/最低位次、省控线数据,好!就他了。
在这一栏数据的上部分有筛选条件,我们就以招生类型作为数据筛选,分析源码后得知这是一个模拟的下拉框。通过selenum内置的定位元素的方法我们进行选择。
这一栏数据还有一个分页,这也是我们要通过selenum模拟点击进行分页模拟。需要处理问题是如何知道数据有没有分页,有多少分页数据。
二、问题处理
- 使用Python+selenium进行数据收录。
- 代码结构:
__init__
初始化数据,定义爬取的目标请求,以及webdriver
初始化。pase_data
主要进行数据分析,数据提取。save_data
数据保存方法。run
程序入口。
- 具体代码
pase_data
方法
def pase_data(self):
self.driver.execute_script('scrollTo(0,400)')
sleep(1)
line_table_box = self.driver.find_elements_by_xpath("//div[@class='line_table_box']/table/tbody/tr[position()>1]")
schoolname = self.driver.find_element_by_xpath(
"//div[@class='schoolName clearfix']/div[@class='line1']/span[@class='line1-schoolName']").text
typename=self.driver.find_element_by_xpath(
"//div[@class='pages app']/div[1]/div[@class='main school_tab_wrap']/div[@class='school-content school_content_1_4 clearfix']/div[@class=' school_content_left_1_4']/div/div[@class='schoolLine clearfix'][1]/div[@class='content-top content_top_1_4']/div[@class='scoreLine-dropDown']/div[@class='dropdown-box'][2]//div[@class='ant-select-selection-selected-value']").text
data_list=[]
for itemtemp in line_table_box:
item = {}
item['school_name'] = schoolname
item['typename'] = typename
ddconent = itemtemp.find_elements_by_xpath("./td")
isAdd=True
for inx,itemContent in enumerate(ddconent):
dd=itemContent.text
if inx==0:
item['year']=dd
elif inx==1:
item['lq_pc'] = dd
elif inx == 2:
item['lqzs_type'] = dd
elif inx == 3:
dd1 = dd[0:dd.find("/")]
dd2 = dd[dd.find("/") + 1:]
item['lq_score'] = dd1
item['lq_wc'] = dd2
elif inx == 4:
item['lq_province_score'] = dd
data_list.append(item)
return data_list
在这个方法中有几个点需要注意一下:
1.收集数据除去表格头使用xpath的谓语[position()>1]。
2.self.driver.execute_script('scrollTo(0,400)')在selenum执行js。处理一些滚动才加载元素。
3.for inx,itemContent in enumerate(ddconent):为循环增加索引,通过判断索引保存对应的数据。
save_data
方法我只是输出到控制台,根据自身情况进行保存到数据库或文件中。run
方法进行了下拉框数据的筛选以及分页的处理。
def run(self):
self.driver.get(self.url)
sleep(0.5)
el_type=self.driver.find_elements_by_xpath("//div[@class='schoolLine clearfix'][1]/div[@class='content-top content_top_1_4']/div[@class='scoreLine-dropDown']/div[@class='dropdown-box']/div[@class='ant-select-lg ant-select ant-select-enabled']")
if len(el_type)>1:
el_type[1].click()
el_selectItems=self.driver.find_elements_by_xpath("//ul[@class='ant-select-dropdown-menu ant-select-dropdown-menu-root ant-select-dropdown-menu-vertical']/li[contains(@class,'ant-select-dropdown-menu-item')]")
for el_item in el_selectItems:
sleep(0.5)
el_item.click()
sleep(0.5)
while True:
data_list=self.pase_data()
self.save_data(data_list)
try:
if len(data_list)>0 and data_list[0]['year']!='-':
el_next=self.driver.find_element_by_xpath("//div[@class='schoolLine clearfix'][1]/div[@class='province_score_line_table']/div[@class='table_pagination_box']/div[@class='pagination_wrap']/div[@class='pagination_box']/ul[@class='ant-pagination ']/li[@class=' ant-pagination-next']/a")
el_next.click()
else:
break
except:
break
el_type[1].click()
el_type[1].click()
print("收集完毕!")
1.通过xpath定位的元素el_type点击获取展现出下拉数据保存在el_selectItems,
通过循环点击收集到的`el_selectItems`数据实现根据高考类型的筛选。
2.通过定位下一页获得的数据el_next,注意根据class属性进行定位当最后一页时
通过抛出异常来跳出分页循环。
可点击下一页的class属性
不可点击的下一页class属性
6. 完整代码
from time import sleep
from selenium import webdriver
class Provinceline(object):
def __init__(self):
self.url='https://gkcx.eol.cn/school/102/provinceline'
self.driver=webdriver.Chrome()
self.driver.get('https://gkcx.eol.cn')
def pase_data(self):
self.driver.execute_script('scrollTo(0,400)')
sleep(1)
line_table_box = self.driver.find_elements_by_xpath("//div[@class='line_table_box']/table/tbody/tr[position()>1]")
schoolname = self.driver.find_element_by_xpath(
"//div[@class='schoolName clearfix']/div[@class='line1']/span[@class='line1-schoolName']").text
typename=self.driver.find_element_by_xpath(
"//div[@class='pages app']/div[1]/div[@class='main school_tab_wrap']/div[@class='school-content school_content_1_4 clearfix']/div[@class=' school_content_left_1_4']/div/div[@class='schoolLine clearfix'][1]/div[@class='content-top content_top_1_4']/div[@class='scoreLine-dropDown']/div[@class='dropdown-box'][2]//div[@class='ant-select-selection-selected-value']").text
data_list=[]
for itemtemp in line_table_box:
item = {}
item['school_name'] = schoolname
item['typename'] = typename
ddconent = itemtemp.find_elements_by_xpath("./td")
isAdd=True
for inx,itemContent in enumerate(ddconent):
dd=itemContent.text
if inx==0:
item['year']=dd
elif inx==1:
item['lq_pc'] = dd
elif inx == 2:
item['lqzs_type'] = dd
elif inx == 3:
dd1 = dd[0:dd.find("/")]
dd2 = dd[dd.find("/") + 1:]
item['lq_score'] = dd1
item['lq_wc'] = dd2
elif inx == 4:
item['lq_province_score'] = dd
data_list.append(item)
return data_list
def save_data(self,data_list):
for item in data_list:
print(item)
def run(self):
self.driver.get(self.url)
sleep(0.5)
el_type=self.driver.find_elements_by_xpath("//div[@class='schoolLine clearfix'][1]/div[@class='content-top content_top_1_4']/div[@class='scoreLine-dropDown']/div[@class='dropdown-box']/div[@class='ant-select-lg ant-select ant-select-enabled']")
if len(el_type)>1:
el_type[1].click()
el_selectItems=self.driver.find_elements_by_xpath("//ul[@class='ant-select-dropdown-menu ant-select-dropdown-menu-root ant-select-dropdown-menu-vertical']/li[contains(@class,'ant-select-dropdown-menu-item')]")
for el_item in el_selectItems:
sleep(0.5)
el_item.click()
sleep(0.5)
while True:
data_list=self.pase_data()
self.save_data(data_list)
try:
if len(data_list)>0 and data_list[0]['year']!='-':
el_next=self.driver.find_element_by_xpath("//div[@class='schoolLine clearfix'][1]/div[@class='province_score_line_table']/div[@class='table_pagination_box']/div[@class='pagination_wrap']/div[@class='pagination_box']/ul[@class='ant-pagination ']/li[@class=' ant-pagination-next']/a")
el_next.click()
else:
break
except:
break
el_type[1].click()
el_type[1].click()
print("收集完毕!")
if __name__ == '__main__':
provinceline=Provinceline()
provinceline.run()
三、结果展示
总结
爬取页面具有针对性,每个需要分析的页面细节不同但流程相同。
对下拉框与分页类型的数据分析有一定的了解。
原创不易动动小手
ε≡٩(๑>₃<)۶ 一心向学
赞一个吧
*:ஐ٩(๑´ᵕ``)۶ஐ:* 赞使我进步