python爬虫获取四川大学2018-2019各省市各专业录取分数线

通过python爬虫在四川大学官网获取四川大学2018-2019各省市各专业录取分数线。

由于官网信息中,2015-2017的数据是存放在一个页面,而2018、2019的数据都是单独的页面,相对规律一些,所以我们今天就来获取2018-2019的信息。

0X00、准备工作

安装标准库lxml、requests、re、requests.exceptions、os和openpyxl。


0X01、页面分析

首先进去是这样的页面:
在这里插入图片描述
标题2018年各省(市、区)分专业录取情况统计表(理工)是这样的:
在这里插入图片描述
而各个省市的名字和链接则是这样:
在这里插入图片描述在这里插入图片描述
弄清楚后比较简单了。
首先还是第一个函数get_page,传入页面url作为参数,获取相应内容,要更改编码为‘utf-8’,不然之后会出现乱码的情况。

def get_page(url):
    try:
        headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0"}
        response = requests.get(url, headers=headers)
        response.encoding = 'utf-8'
        if response.status_code == 200:
            return response.text
        else:
            return None
    except RequestException:
        return None

然后就是第二个函数get_link,获取每个主页面下的所有省市的名字和链接。

首先通过xpathtitle = text.xpath('//form[@name="_newscontent_fromname"]/h2/text()')获取当前页面的标题,然后通过正则表达式得到当前页面所属的年份与类别(理工,文史),以备后续使用。
通过之前获取的信息,得到我们存放所有链接的文件的名字,如果文件不存在则新建文件。
吸取了昨天的教训,好好看了一下xpath,

link_content = text.xpath('//td/p/a/@href')
province_content = text.xpath('//td/p/a/text()')

拿到所有的链接和名字,将其存入文件中。注意这里获得的链接是 相对路径,加上前面的内容补充为完整链接。

def get_link(text):
    text = etree.HTML(text)
    # xpath获取页面标题"201x年各省(市、区)分专业录取情况统计表(xx)"
    title = text.xpath('//form[@name="_newscontent_fromname"]/h2/text()')
    title_content = re.findall('(\\d*)年各省\\(市、区\\)分专业录取情况统计表((.{2}))', title[0], flags=0)
    # 获取当前页面所属的年份与类别(理工,文史)
    year = str(title_content[0][0])
    data_type = str(title_content[0][1])
    # 打开文件
    file_name = year + '(' + data_type + ')' + '各省市链接.xlsx'
    if os.path.exists(file_name):
        print('文件' + file_name + '已存在!')
        wb = openpyxl.load_workbook(file_name)
        print('文件' + file_name + '打开成功!')
    else:
        wb = openpyxl.Workbook()  # 创建文件对象
        print('文件' + file_name + '创建成功!')
    ws = wb.active
    ws['A1'] = '年份'
    ws['B1'] = '类别'
    ws['C1'] = '省份'
    ws['D1'] = '链接'
    # 下一次填入数据的行数
    index = 2
    link_content = text.xpath('//td/p/a/@href')
    province_content = text.xpath('//td/p/a/text()')
    for i in range(len(link_content)):
        ws.cell(index, 1, year)
        ws.cell(index, 2, data_type)
        ws.cell(index, 3, province_content[i])
        link = 'http://zs.scu.edu.cn/info' + link_content[i].strip('..')
        ws.cell(index, 4, link)
        print(year + '年' + province_content[i] + '普通类录取分数线统计表(' + data_type + ')链接写入成功!')
        index += 1
    print(year + '年所有省市普通类录取分数线统计表(' + data_type + ')链接写入完成!')
    wb.save(filename=file_name)

拿到每个省市信息的链接后,下一步来分析信息页面:
在这里插入图片描述页面标题和之前的一样,只是注意一下用xpath的时候form标签的name属性值变了,其他的和上一个页面一样。
在这里插入图片描述
而下面的专业数据则是在td标签下的span标签中(要注意一下19年理工的页面没有这个span标签,所以代码要做一下判断是不是19年理工)
在这里插入图片描述在这里插入图片描述
下面就是得到页面数据的函数parse_one_page,传入url参数,还是先获取页面标题,正则表达式获取页面所属的年份、省份与类别(理工,文史)。
下面的操作和之前差不多。

然后这里判断一下是不是19年理工,选择不同的xpath表达式,然后将其写入文档。

通过判断列数是不是等于6,等于6的话则该专业数据填写完毕,转到下一行。保存文件即可。

def parse_one_page(data_url):
    data_text = get_page(data_url)
    data_text = etree.HTML(data_text)
    title = data_text.xpath('//form[@name="_newscontent_fromname"]/h2/text()')
    title_content = re.findall('(\\d*)年(.*?)普通类录取分数线统计表\\((.{3})\\)', title[0], flags=0)
    # 获取当前页面所属的年份、省份与类别(理工,文史)
    year = str(title_content[0][0])
    province = str(title_content[0][1])
    data_type = str(title_content[0][2])

    # 打开文件
    file_name = year + '(' + data_type + ')/' + year + '(' + data_type + ')' + province + '各专业录取分数.xlsx'
    folder_name = year + '(' + data_type + ')'
    if not os.path.exists(folder_name):  # 如果路径不存在
        os.makedirs(folder_name)
    if os.path.exists(file_name):
        print(file_name + '已存在!')
        return None
    else:
        wb = openpyxl.Workbook()  # 创建文件对象
        print('文件' + file_name + '创建成功!')
    ws = wb.active
    ws['A1'] = '专业名称'
    ws['B1'] = '最高分'
    ws['C1'] = '最低分'
    ws['D1'] = '平均分'
    ws['E1'] = '录取人数'
    index = 2
    columns = 1
    if (year == 2019) & (data_type == '理工'):
        content = data_text.xpath('//tbody/tr/td/text()')
    else:
        content = data_text.xpath('//tbody/tr/td/span/text()')
    for i in range(5, len(content)):
        ws.cell(index, columns, content[i])
        columns += 1
        if columns == 6:
            index += 1
            columns = 1
    print(file_name + '写入完毕')
    wb.save(filename=file_name)

接下来就是函数send_links,将之前保存在文档中的链接逐个读取,传入函数parse_one_page,以此获取每个省份数据。

def send_links():
    year = input('请输入要获取数据的年份:')
    type = input('请输入要获取数据的类别(理工/文史):')
    file_name = year + '(' + type + ')各省市链接.xlsx'
    try:
        wb = openpyxl.load_workbook(file_name)
        ws = wb.active
        a = 'a'
        i = 2
        while a != '':
            a = ws.cell(i, 4).value
            if a is not None:
                parse_one_page(a)
                i += 1
            else:
                print(year + '(' + type + ')数据获取完毕')
                return
    except FileNotFoundError:
        print('不存在输入信息的文件,请检查输入!')

0X03、完整代码

import requests
from requests.exceptions import RequestException
from lxml import etree
import re
import os
import openpyxl


def get_page(url):
    try:
        headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0"}
        response = requests.get(url, headers=headers)
        response.encoding = 'utf-8'
        if response.status_code == 200:
            return response.text
        else:
            return None
    except RequestException:
        return None


def get_link(text):
    text = etree.HTML(text)
    # xpath获取页面标题"201x年各省(市、区)分专业录取情况统计表(xx)"
    title = text.xpath('//form[@name="_newscontent_fromname"]/h2/text()')
    title_content = re.findall('(\\d*)年各省\\(市、区\\)分专业录取情况统计表((.{2}))', title[0], flags=0)
    # 获取当前页面所属的年份与类别(理工,文史)
    year = str(title_content[0][0])
    data_type = str(title_content[0][1])
    # 打开文件
    file_name = year + '(' + data_type + ')' + '各省市链接.xlsx'
    if os.path.exists(file_name):
        print('文件' + file_name + '已存在!')
        wb = openpyxl.load_workbook(file_name)
        print('文件' + file_name + '打开成功!')
    else:
        wb = openpyxl.Workbook()  # 创建文件对象
        print('文件' + file_name + '创建成功!')
    ws = wb.active
    ws['A1'] = '年份'
    ws['B1'] = '类别'
    ws['C1'] = '省份'
    ws['D1'] = '链接'
    index = 2
    link_content = text.xpath('//td/p/a/@href')
    province_content = text.xpath('//td/p/a/text()')
    for i in range(len(link_content)):
        ws.cell(index, 1, year)
        ws.cell(index, 2, data_type)
        ws.cell(index, 3, province_content[i])
        link = 'http://zs.scu.edu.cn/info' + link_content[i].strip('..')
        ws.cell(index, 4, link)
        print(year + '年' + province_content[i] + '普通类录取分数线统计表(' + data_type + ')链接写入成功!')
        index += 1
    print(year + '年所有省市普通类录取分数线统计表(' + data_type + ')链接写入完成!')
    wb.save(filename=file_name)


def parse_one_page(data_url):
    data_text = get_page(data_url)
    data_text = etree.HTML(data_text)
    title = data_text.xpath('//form[@name="_newscontent_fromname"]/h2/text()')
    title_content = re.findall('(\\d*)年(.*?)普通类录取分数线统计表\\((.{3})\\)', title[0], flags=0)
    # 获取当前页面所属的年份、省份与类别(理工,文史)
    year = str(title_content[0][0])
    province = str(title_content[0][1])
    data_type = str(title_content[0][2])

    # 打开文件
    file_name = year + '(' + data_type + ')/' + year + '(' + data_type + ')' + province + '各专业录取分数.xlsx'
    folder_name = year + '(' + data_type + ')'
    if not os.path.exists(folder_name):  # 如果路径不存在
        os.makedirs(folder_name)
    if os.path.exists(file_name):
        print(file_name + '已存在!')
        return None
    else:
        wb = openpyxl.Workbook()  # 创建文件对象
        print('文件' + file_name + '创建成功!')
    ws = wb.active
    ws['A1'] = '专业名称'
    ws['B1'] = '最高分'
    ws['C1'] = '最低分'
    ws['D1'] = '平均分'
    ws['E1'] = '录取人数'
    index = 2
    columns = 1
    if (year == 2019) & (data_type == '理工'):
        content = data_text.xpath('//tbody/tr/td/text()')
    else:
        content = data_text.xpath('//tbody/tr/td/span/text()')
    for i in range(5, len(content)):
        ws.cell(index, columns, content[i])
        columns += 1
        if columns == 6:
            index += 1
            columns = 1
    print(file_name + '写入完毕')
    wb.save(filename=file_name)


def send_links():
    year = input('请输入要获取数据的年份:')
    type = input('请输入要获取数据的类别(理工/文史):')
    file_name = year + '(' + type + ')各省市链接.xlsx'
    try:
        wb = openpyxl.load_workbook(file_name)
        ws = wb.active
        a = 'a'
        i = 2
        while a != '':
            a = ws.cell(i, 4).value
            if a is not None:
                parse_one_page(a)
                i += 1
            else:
                print(year + '(' + type + ')数据获取完毕')
                return
    except FileNotFoundError:
        print('不存在输入信息的文件,请检查输入!')


url = {'2019理工': 'http://zs.scu.edu.cn/info/1037/2083.htm',
       '2019文史': 'http://zs.scu.edu.cn/info/1037/2128.htm',
       '2018理工': 'http://zs.scu.edu.cn/info/1037/1370.htm',
       '2018文史': 'http://zs.scu.edu.cn/info/1037/1489.htm', }
choice = input('请输入想获取的年份与类别各省份总链接(2018理工、2018文史、2019理工、2019文史):')
try:
    text = get_page(url[choice])
    if text is not None:
        get_link(text)
        send_links()
except KeyError:
    print('输入有误,请检查输入!')

0X04、反思

其实回过头来看代码还是比较简单的,但是还是花了很多时间(害),19理工和其他页面不同这,排查了半天才注意到,细心程度有待提高。

还有新建文件夹,在文件夹下新建文件这,也搞错了好几次。

一天比一天进步一点,加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值