爬取大学排名
有些网页源码中找不到相应的要爬的数据,其实这不是什么被反扒了,只是网页有可能是动态加载出来,这时候我们可以找到相应的数据接口,找到真正的目标url一样能找到包含我们想要的数据的真正url,就像我今天要讲的这个案例。  右键查看网页源码,我们会发现数据虽然存在于网页源码中,但是,我们点一下翻页功能,再观察 第一页  第二页  我们会发现,无论我们怎么翻页,url 都是不变的,这个时候,我们应该考虑网页是不是动态加载出来的。在 “开发者工具”->“网络” 中找看看有没有相应的数据接口,一找果然是  发现数据是保存在一个js格式的文件中的,下面才是它真正url 
如果用传统的方法去爬,就会经历一个较为繁琐的数据解析过程。所以这时候,selenium的好处就体现出来了,直接获取页面元素,虽然有点慢,但是我们不用再经历繁琐的解析过程。
页面分析
直接查看页面元素  发现每个大学的数据信息都是保存在一个 tr 标签中的,再分析就会发现,每个大学的详细信息分别保存在一个 td 标签中 
需求
(一)获取大学排名、名称、类型、地点等信息 (二)以csv文件格式保存文件 (三)以面向对象的形式实现
实现代码
只需要用到两个包,selenium.webdriver和csv模块。详细的实现步骤我都在代码中做了注释,就不再多做说明了 要强调的是翻页的处理,分别分析一下最后一页和其他页下的“下一页”按钮有什么区别 
 我们会发现,在没到达最后一页时,下一页标签中没有 aria-disabled="true"这个值,到了最后一页才出现的,也就说明,当我们到达最后一页后,下一页按钮就不能再点了,所以找到了这个翻页就相当简单了,话不多说,上代码
from selenium import webdriver
import csv
class Univercity(object):
def __init__(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.header = ['Rank','Cn','En','Rate','Location','Type']
self.data = []
options = webdriver.ChromeOptions()
options.add_argument('--headless')
self.driver = webdriver.Chrome(options=options)
def parse_html(self,url):
self.driver.get(url)
self.driver.implicitly_wait(1)
while True:
tr_list = self.driver.find_elements_by_xpath('.//*[@id="content-box"]/div[2]/table/tbody/tr')
for tr in tr_list:
items = {}
items['Rank'] = tr.find_element_by_xpath('.//td/div').text
items['Cn'] = tr.find_element_by_class_name('name-cn').text
items['En'] = tr.find_element_by_class_name('name-en').text
try:
items['Rate'] = tr.find_element_by_class_name('tags').text
except:
items['Rate'] = ""
items['Location'] = tr.find_element_by_xpath('.//td[3]').text
items['Type'] = tr.find_element_by_xpath('.//td[4]').text
self.data.append(items)
if self.driver.page_source.find('ant-pagination-disabled ant-pagination-next') == -1:
self.driver.find_element_by_class_name('ant-pagination-next').click()
self.driver.implicitly_wait(2)
else:
break
def save_data(self,header,data):
with open('test.csv', 'a', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=header)
writer.writeheader()
writer.writerows(data)
def main(self):
url = 'https://www.shanghairanking.cn/rankings/bcur/202111'
self.parse_html(url)
self.save_data(self.header,self.data)
if __name__ == '__main__':
u = Univercity()
u.main()
实现效果
 到这,这个案例就算结束了,是不是很简单?
|