python爬虫大学排行榜

思路:

爬虫必备三件套:

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:试着打印一下,发现排名,省份,分数多出来斜杠

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATG9ycmV5Xw==,size_20,color_FFFFFF,t_70,g_se,x_16

解决方法:

 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]

成功 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATG9ycmV5Xw==,size_20,color_FFFFFF,t_70,g_se,x_16

完整代码:

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)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATG9ycmV5Xw==,size_20,color_FFFFFF,t_70,g_se,x_16

发现爬取了590个,所以可以确定590是界限,不能超出这个

问题3:这里打开xlsx文件发现,省份都变成了不认识的

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATG9ycmV5Xw==,size_20,color_FFFFFF,t_70,g_se,x_16

这里使用了编号,是网页开发者为了反爬所设计的

解决办法:

1.在打开的xlsx文件中新建一个工作表,把内容全部复制过去

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATG9ycmV5Xw==,size_20,color_FFFFFF,t_70,g_se,x_16

2.在数据里删除重复值

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATG9ycmV5Xw==,size_20,color_FFFFFF,t_70,g_se,x_16

取消全选,勾选省份,及删除省份相同值的列

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATG9ycmV5Xw==,size_15,color_FFFFFF,t_70,g_se,x_16

3.在新的一列写出省份,并将工作表另存一个xlsx文件

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATG9ycmV5Xw==,size_20,color_FFFFFF,t_70,g_se,x_16

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文件,已经改好

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATG9ycmV5Xw==,size_20,color_FFFFFF,t_70,g_se,x_16

感谢各位能看完,如果觉得有帮助,那请点个赞吧

猜你喜欢

转载自blog.csdn.net/Lorrey_/article/details/124277043
今日推荐