思路:
爬虫必备三件套:
import requests
url='https://www.shanghairanking.cn/_nuxt/static/1650334172/rankings/bcur/202211/payload.js'
r=requests.get(url)
我们同样可以使用xpath来获取:
from lxml import html
ht=html.fromstring(r.text)
到该网页检查里元素找到需要爬取内容的xpath路径:
进入网页,右击检查,元素,根据网页中元素进行搜查,找到后右击copy,复制XPath
大致步骤是这样,不懂在下面问我
排名:university_rank=ht.xpath('//*[@id="content-box"]/div[2]/table/tbody/tr/td[1]/div/text()')
院校名称:university_name=ht.xpath
('//[@id="contentbox"]/div[2]/table/tbody/tr/td[2]/div/div[2]/div[1]/div/div/a/text()')
省份:university_city=ht.xpath('//*[@id="content-box"]/div[2]/table/tbody/tr/td[3]/text()')
分数:university_score=ht.xpath('//*[@id="content-box"]/div[2]/table/tbody/tr/td[5]/text()')
问题1:试着打印一下,发现排名,省份,分数多出来斜杠
解决方法:
university_rank=[place.strip() for place in university_rank]
university_city=[place.strip() for place in university_city]
university_score=[place.strip() for place in university_score]
成功
完整代码:
import requests
from lxml import html
from openpyxl import Workbook
url='https://www.shanghairanking.cn/rankings/bcur/202211'
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36'}
r=requests.get(url) #获取数据
r.encoding='utf-8' #格式
retext=r.text #写入
ht=html.fromstring(retext) #解析
university_rank=ht.xpath('//*[@id="content-box"]/div[2]/table/tbody/tr/td[1]/div/text()')
university_rank=[place.strip() for place in university_rank]
university_name=ht.xpath('//*[@id="content-box"]/div[2]/table/tbody/tr/td[2]/div/div[2]/div[1]/div/div/a/text()')
university_city=ht.xpath('//*[@id="content-box"]/div[2]/table/tbody/tr/td[3]/text()')
university_city=[place.strip() for place in university_city]
university_score=ht.xpath('//*[@id="content-box"]/div[2]/table/tbody/tr/td[5]/text()')
university_score=[place.strip() for place in university_score]
#print(university_rank,university_name,university_city,university_score)
#整理格式:排名,院校名称,省份,分数
unvilist=[]
for i in range(len(university_rank)):
url = 'https://www.shanghairanking.cn/rankings/bcur/202211'
unvilist.append([i+1,university_name[i],university_city[i],university_score[i]])
print(unvilist)
#第二种整理
# resultlist=[]
# resultlist=list(zip(university_rank,university_name,university_city,university_score))
# print(resultlist)
#创建Excel
filename='大学排行榜1.xlsx'
wb=Workbook()
sheet=wb.active
sheet.append(['排名','院校名称','省份','得分'])
#写入内容
for i in unvilist:
sheet.append(i)
wb.save(filename)
问题2:发现只爬取了前30名,想多爬怎么办?
修改url?这时候发现,翻页后url并没有变,是因为这是动态页面,我们之前爬取的是静态
找到新js url:
url='https://www.shanghairanking.cn/_nuxt/static/1650334172/rankings/bcur/202211/payload.js'
所以这里我们可以用正则表达式
# -- coding: utf-8 --
import requests
from openpyxl import Workbook
import re
#读取对应js代码
url='https://www.shanghairanking.cn/_nuxt/static/1650334172/rankings/bcur/202211/payload.js'
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36'}
r=requests.get(url)
r.encoding='utf-8'
retext=r.text
#由于是动态网页,爬取多页要用正则表达式
#使用正则表达式
univnamelist=re.findall('univNameCn:"(.*?)"', retext)
pronlist=re.findall('province:(.*?),' , retext)
scorelist=re.findall('score:(.*?),' , retext)
#print(univnamelist)
unvilist=[]
for i in range(len(univnamelist)):
url = 'https://www.shanghairanking.cn/_nuxt/static/1650334172/rankings/bcur/202211/payload.js'
unvilist.append([i+1,univnamelist[i],pronlist[i],scorelist[i]])
print(unvilist)
filename='大学排行榜.xlsx'
wb=Workbook()
sheet=wb.active
sheet.append(['排名','院校名称','省份','得分'])
for i in unvilist:
sheet.append(i)
wb.save(filename)
发现爬取了590个,所以可以确定590是界限,不能超出这个
问题3:这里打开xlsx文件发现,省份都变成了不认识的
这里使用了编号,是网页开发者为了反爬所设计的
解决办法:
1.在打开的xlsx文件中新建一个工作表,把内容全部复制过去
2.在数据里删除重复值
取消全选,勾选省份,及删除省份相同值的列
3.在新的一列写出省份,并将工作表另存一个xlsx文件
4.在原来代码上进行修改
import requests
from openpyxl import Workbook
from openpyxl import load_workbook
import re
#获取省份编号
filename1='省份编号.xlsx'
#读取Excel表
wb1=load_workbook(filename1) #工作簿对象
ws=wb1[wb1.get_sheet_names()[0]] #工作表对象,工作表名称=wb1['sheet1']
prov={}
#遍历数据表,生成字典格式
for i in range(ws.max_row-1): #max_row 最大行
prov[ws['C'+str(i+2)].value]=ws['E'+str(i+2)].value
#prov[ws.cell(row=i+2,column=3).value]=ws.cell(row=i+2,column=5).value
print(prov)
#读取对应js代码
url='https://www.shanghairanking.cn/_nuxt/static/1650334172/rankings/bcur/202211/payload.js'
r=requests.get(url)
r.encoding='utf-8'
retext=r.text
#由于是动态网页,爬取多页要用正则表达式
#使用正则表达式
univnamelist=re.findall('univNameCn:"(.*?)"', retext)
pronlist=re.findall('province:(.*?),' , retext)
scorelist=re.findall('score:(.*?),' , retext)
#print(univnamelist)
#构造保存Excel数据
unvilist=[]
for i in range(len(univnamelist)):
unvilist.append([i+1,univnamelist[i],prov[pronlist[i]],scorelist[i]])
print(unvilist)
#保存Excel文件
filename='大学排行榜.xlsx'
wb=Workbook()
sheet=wb.active
sheet.append(['排名','院校名称','省份','得分'])
for i in unvilist:
sheet.append(i)
wb.save(filename)
这时候再打开xlsx文件,已经改好
感谢各位能看完,如果觉得有帮助,那请点个赞吧