Mr.Wjs 发表于 2021-1-16 18:45

根据老哥riwfhiu的框架,实践爬取教务处查询成绩模块

首先感谢@riwfhiu 老哥给的爬虫框架

首先伪装访问请求头:

这是内网的地址,不知道能不能写一段代码在爬数据之前先自动连接VPN。


然后定位要爬取数据:


接下来就是根据老哥的框架,抄作业了



import requests,json
from lxml import etree


# =====================================请求区==========================================#
# get模式,获取网页源码,传入参数:url(字符串)
def gethtml(url):
    # 伪装头文件,F12打开浏览器,刷新一次:Network > 选目标链接(默认第一个) > Headers
    headers = {
      # User-Agent 浏览器标识头,爬虫必备,最好带上。
      "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
      "Cookie": "semester.id=382; JSESSIONID=2F6A26DDD9116DDEB7185FDE50453636",# cookie相当于临时登陆凭证,作用跟账号密码一样,有效期由网站决定,几天到几月不等。带cookies伪装表示已登陆状态。
      "Referer": "http://192.168.0.88",# Referer表示来源地址,有些网站会检测跨域访问,不合法会拒绝。
      # 剩下其它的一些伪装如果能正常访问可以不添加,不能就加上吧
      # "Upgrade-Insecure-Requests": "1",      #比如这个属性是百度网址的,其它网址可能有其它属性值
    }
    r = requests.get(url, headers=headers)# 正式get请求
    if r.status_code != 200:# 状态码判断返回是否成功,不成功则报错退出
      print("获取url:%s失败!" % (url))
      exit()
    return r# 直接返回r,为什么不直接返回r.text(文本),因为图片/视频格式是r.content(用二进制写入)


# =====================================解析区==========================================#
# xpath解析接口,输入:xpath格式字符串'//div/img[@id="s_lg_img_new"]'注意外面一层是单引号,返回值为list,元素为字符串
# 我个人推荐xpath,轻巧强大好用,浏览器自带解析路径,不会写的直接无脑copy,右键元素 > Copy > CopyXpath,复制字符串传入参数即可
# xpath字符串通用写法://标签[@属性="属性值"]/下一级标签[@属性="属性值"]/text() 取出文本 /@src取出src地址
# 例子://div[@class="text-content"]/a/@href      #取出div下的第2个a的href属性值。
def getxpath(r, str):
    html = etree.HTML(r.text)
    reslist = html.xpath(str)
    return reslist



# =====================================保存区==========================================#
# 爬虫目的一般为获取文本/图片/视频等数据,一般要保存下来慢慢看
# 文本写入txt,传入参数:txtpath路径,data数据
def writetxt(txtpath, data_str):# 文本的名字和路径,也可以使用绝对路径,例如 "D:\\爬虫学习\\采集文本.txt"
    with open(txtpath, "w") as f:
      f.write(str(data_str))



# 图片写入jpg/png,传入参数:imgpath路径,content二进制数据
def writeimg(imgpath, content):# 图片的名字和路径
    with open(imgpath, "wb") as f:
      f.write(content)


# ================以上三大块就是通用爬虫模板,下面是自己写的想实现的功能====================#
# 获取成绩,并写入txt中
def get_news_txt():
    # 第一步:请求网址先获取html
    url = "http://192.168.0.88/eams/teach/grade/course/person!search.action?semesterId=382&projectType=&_=1610787238866"
    r = gethtml(url)
    title_xpath='//*[@id="grid3700032241"]/thead/tr/th/text()'       #th没有选中具体值,返回所有匹配的值
    title_list=getxpath(r,title_xpath)            #传入r页面源码
    title_str=""
    for one in title_list:
      print(one)
      title_str+=str(one)+""
    with open("成绩.txt",'a') as txt:         
      a=txt.write(title_str)
      a=txt.write("\n")
    print(str(title_str))
    print("恭喜你写入了一个爬虫数据!快打开文件看看吧")

    title_xpath = '//*[@id="grid3700032241_data"]/tr/td/text()'# th没有选中具体值,返回所有匹配的值
    title_list = getxpath(r, title_xpath)# 传入r页面源码
    title_str = ""
    for one in title_list:
      print(one)
      title_str += str(one) + ""
    with open("成绩.txt", 'a') as txt:
      a = txt.write(title_str)
    print(str(title_str))

get_news_txt()



爬取成功



不知道为什么这里自动换行了,如果写入CSV文件会不会就有格式了?

实在惭愧,搞了一个来小时才搞好。

在学校学了一学期的Python,老师就讲了点基础的东西,希望下学期上这个老师的电子商务推荐系统能学到更多东西吧!

最后再次感谢@riwfhiu !!!
终于感受到Pyhthon的一点用途了。。。。。





耿梦莹123 发表于 2021-1-16 21:00

牛!!!!

riwfhiu 发表于 2021-1-17 15:52

哈哈,受宠若惊,没想到还真的能帮助到别人,我很开心!再帮你完善一下吧。
至于vpn连校内网,我搞不定哦,因为协议很多,暂时没发现好用的模块,你可以手动在本机上连接后再运行,你浏览器能访问的,代码一样能行。
想写入csv真是太简单了,转成多行列表形式就可以了,代码直接贴上。
import requests,json
from lxml import etree
#写入csv用python自带的包就可以了,time模板可以提供13位的时间戳避免系统检测(不过只有内网的教务系统没有人去理这些的的哈哈过来人)
import csv,time


#获取网页
def gethtml(url):
        headers = {
    "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
    "Cookie": "semester.id=382; JSESSIONID=2F6A26DDD9116DDEB7185FDE50453636",
    "Referer": "http://192.168.0.88",
    }
    r = requests.get(url, headers=headers)
    if r.status_code != 200:
      print(f"获取url:{url}失败!")
      exit()
    return r

#解析xpath路径
def getxpath(r, str):
    html = etree.HTML(r.text)
    reslist = html.xpath(str)
    return reslist


#写入csv , 输入参数:csvpath路径,table_list列表式数据,输出:无(直接写入文件csv)
def write_csv(csvpath,table_list):
        with open(csvpath,"w",newline='') as f:
                mycsv=csv.writer(f)
                mycsv.writerows(table_list)


#获取成绩
def get_grade():
        t = int(time.time()*1000)                #13位的时间戳,比如:1610787238866,这样就不用写死在链接里了,虽然教务系统也没人管但最好是能自适应的
        url = "http://192.168.0.88/eams/teach/grade/course/person!search.action?semesterId=382&projectType=&_=%s"%(t)
    r = gethtml(url)
    #获取表头
    title_xpath = '//*[@id="grid3700032241"]/thead/tr/th/text()'
    title_list = getxpath(r,title_xpath)
    #获取的数据只好能格式化,比如想写入csv就用列表list来装,返回值title_list已经是列表了,就没有必须再进行转列表处理了

    #获取表内数据
    grade_xpath = '//*[@id="grid3700032241_data"]/tr/td/text()'
    grade_list = getxpath(r,grade_xpath)

    #转成多行列表形式,(因为返回值是一长串列表,需要切割换行,转成嵌套列表)
    col = int(len(title_list))                                        #列数:跟表头一样个数
    row = int(int(len(grade_list)) / int(col))        #行数:自动计算
    table_list=[]                        #用table列表来装所有表格
    table_list.append(title_list)        #先装入表头
    #切割换行数据,为了方便理解,x表示行(用不上),y表示列
    for y in range(row):
            one_list = grade_list                #从y行第0个 到 y行+col个,即第y整行的数据one_list
            table_list.append(one_list)
    #你可以打印一下是不是整齐的嵌套列表结构table_list=[[],[],[],[]]
    print(table_list)


    #===============写入csv==================#
    csvpath="成绩.csv"
    write_csv(csvpath,table_list)
    print("已写入csv,快去看看吧!")


if __name__ == '__main__':
        get_grade()

Left 发表于 2021-5-22 14:52

这个教务系统不需要登录吗

Mr.Wjs 发表于 2021-5-24 01:20

Left 发表于 2021-5-22 14:52
这个教务系统不需要登录吗

cookie登录

Left 发表于 2021-5-29 16:26

Mr.Wjs 发表于 2021-5-24 01:20
cookie登录

有办法通过账号密码登录吗?
页: [1]
查看完整版本: 根据老哥riwfhiu的框架,实践爬取教务处查询成绩模块