用爬虫爬取重邮教师信息

  • 结果展示
  • 代码实现
  • 主网页分析
  • 教师界面分析
  • 主要代码分析
  • 后记


结果展示

python3 爬虫 笑话 爬虫python案例_爬虫

由于数据量比较大,我结果只截取了一部分。

代码实现

import requests
from requests.exceptions import RequestException
from lxml import etree
import json
import time

def get_url(num):
    """输入num 生成需要爬取的url"""
    url_1 = "http://software.cqupt.edu.cn/info/1006/"
    url_2 = ".htm"
    url = url_1+str(num)+url_2
    #print(url)
    return url

def get_one_page(url):
    """爬取一页的源代码,并且返回html"""
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
                          + 'AppleWebKit/537.36 (KHTML, like Gecko)'
                          + 'Chrome/73.0.3683.103 Safari/537.36',
        }
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            response.encoding = "utf-8"  #声明‘UTF-8’编译方式,否则乱码
            print('爬取成功')
            return response.text
        else:
            print('爬取失败')
            fall = response.status_code
            print(str(fall))
            print(url)
        #response.encoding = "utf-8"
        #print(response.text)
        #print('-----------------------------------------------------------------------------------------------------------------------------------------------------------------')
        return response.text
    except RequestException:
        return None

def dell_one_page(html):
    #html1 = etree.parse(html,etree.HTMLParser())#
    html1 = etree.HTML(html)
    #result = etree.tostring(html1) '就是这行代码把html的格式改了,导致那个新的格式没有了xpath方法'
    #print(type(html1))
    name = html1.xpath('//p/strong/text()')
    what = html1.xpath('//p/text()')
    #print(name)
    #print(what)
    info = {
        'name' :name,
        'info' :what,
    }
    infom = {}
    #print(info)
    #return info
    if what:
        return info
    else:
        return infom

def write_download(info):
    if info:
        with open(r'C:\Users\DDH\Desktop\cquptteachers.txt','a',encoding='utf-8') as f:
            f.write(json.dumps(info,ensure_ascii=False)+'\n\n')
    else:
        with open(r'C:\Users\DDH\Desktop\cquptteachers.txt','a',encoding='utf-8') as f:
            f.write("URL错误爬取失败尝试爬取下一个节点"+'\n\n')

def main(num):
    '''main函数进行html的爬取'''
    url = get_url(num) #生成url
    html = get_one_page(url)  #将生成的url的html爬取下来
    info = dell_one_page(html)
    write_download(info)

if __name__ == '__main__':
    """生成num"""
    for num in range(1961, 2418, 1):
        main(str(num))
        time.sleep(1)

主网页分析

本次爬取的URL为:http://software.cqupt.edu.cn/list.jsp?urltype=tree.TreeTempUrl&wbtreeid=1006](http://software.cqupt.edu.cn/list.jsp?urltype=tree.TreeTempUrl&wbtreeid=1006) 传送门

首先进如网站发现全校在职教师的简介:

python3 爬虫 笑话 爬虫python案例_爬虫_02

点击第一名教师进入该教师的个人界面:

python3 爬虫 笑话 爬虫python案例_python3 爬虫 笑话_03


而此时的URL变更为了: http://software.cqupt.edu.cn/info/1006/2417.htm 传送们点击第二名教师进入该教师的个人界面:

python3 爬虫 笑话 爬虫python案例_json_04


此时的URL为:http://software.cqupt.edu.cn/info/1006/2415.htm
分析URL的变换:http://software.cqupt.edu.cn/list.jsp?urltype=tree.TreeTempUrl&wbtreeid=1006
http://software.cqupt.edu.cn/info/1006/2417.htm http://software.cqupt.edu.cn/info/1006/2415.htm
观察URL的变换可知控制教师信息的URL为URL末尾的四位数字第一位与第二位间隔为2
同时找到下一页的URL:

python3 爬虫 笑话 爬虫python案例_html_05

教师界面分析

查看教师界面的网页源代码:

python3 爬虫 笑话 爬虫python案例_html_06


发现教师的所有信息都在div的id="vsb_content的块当中因此我选择的是XPath,根据这些标签分别写出所需要的信息的选择器。

主要代码分析

for num in range(1961, 2418, 1):
        main(str(num))
        time.sleep(1)
        
 def get_url(num):
    """输入num 生成需要爬取的url"""
    url_1 = "http://software.cqupt.edu.cn/info/1006/"
    url_2 = ".htm"
    url = url_1+str(num)+url_2
    #print(url)
    return url

首先构建了需要爬取的URL(第一次爬去的时候提取了下一页的URL但是后面发现可以直接控制URL最后四位数字来改变需要爬去的界面,而且第一次爬取时发现URL的不是每一位教师之间相差2,因此在构建URL时选择了构建1961到2418之间的所有URL);

def get_one_page(url):
    """爬取一页的源代码,并且返回html"""
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
                          + 'AppleWebKit/537.36 (KHTML, like Gecko)'
                          + 'Chrome/73.0.3683.103 Safari/537.36',
        }
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            response.encoding = "utf-8"  #声明‘UTF-8’编译方式,否则乱码
            print('爬取成功')
            return response.text
        else:
            print('爬取失败')
            fall = response.status_code
            print(str(fall))
            print(url)
        #response.encoding = "utf-8"
        #print(response.text)
        #print('-----------------------------------------------------------------------------------------------------------------------------------------------------------------')
        return response.text
    except RequestException:
        return None

常规操作,构建headers,然后发送请求,得到访问网页的源代码;

def dell_one_page(html):
    #html1 = etree.parse(html,etree.HTMLParser())#
    html1 = etree.HTML(html)
    #result = etree.tostring(html1) '就是这行代码把html的格式改了,导致那个新的格式没有了xpath方法'
    #print(type(html1))
    name = html1.xpath('//p/strong/text()')
    what = html1.xpath('//p/text()')
    #print(name)
    #print(what)
    info = {
        'name' :name,
        'info' :what,
    }
    infom = {}
    #print(info)
    #return info
    if what:
        return info
    else:
        return infom

def write_download(info):
    if info:
        with open(r'C:\Users\DDH\Desktop\cquptteachers.txt','a',encoding='utf-8') as f:
            f.write(json.dumps(info,ensure_ascii=False)+'\n\n')
    else:
        with open(r'C:\Users\DDH\Desktop\cquptteachers.txt','a',encoding='utf-8') as f:
            f.write("URL错误爬取失败尝试爬取下一个节点"+'\n\n')

用XPath提取数据,并且保留到本地(我是用的TXT保存的,没钱买不起数据库),因为构建的URL当中有一些URL为空,所以我写出了当URL错误时输出"URL错误爬取失败尝试爬取下一个节点;"

后记

  • 这个网站的URL变换没有规律,因此选择直接构建在变换区间当中的所有URL,导致一些URL为空,降低了爬虫的爬取效率;
  • 在后期的分析当中发现,每一个教师主页的源代码不一致,也就是说第一个教师的名字可能在p标签当中而第二个教师名字信息在其他标签当中,这导致提取数据时没有统一的提取函数,因此我选择为满足大多数教师主页的网页代码写提取函数,而那些不满足的返回一个【】空的字典;
  • 这个网站没有防爬机制,适合像我一样的小白练手;
  • 我的第一个爬虫和第一篇博客就这样吧,继续加油,学习ing。