ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

20212113齐振华 《Python程序设计》第四次实验报告

2022-05-27 23:00:42  阅读:195  来源: 互联网

标签:__ name format Python 20212113 python print 实验报告 opts


课程:《Python程序设计》
班级: 2121
姓名: 齐振华
学号:2021213
实验教师:王志强
实验日期:2022年5月22日
必修/选修: 公选课

1.实验内容

Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
注:在华为ECS服务器(OpenOuler系统)和物理机(Windows/Linux系统)上使用VIM、PDB、IDLE、Pycharm等工具编程实现。

2. 实验过程及结果

实验分析:

  目的:爬取12306上从北京发往济南的车票情况,并实现可视化,可视化采取pyecharts,可视化一等座每个车次剩余情况,二等座车次剩余情况,利用python模拟浏览器爬取数据。

实验设计:

  获取网站url,cookie,和user – agent,利用内置模块requests 爬取数据,爬取的数据转为json,并利用正则表达式获取想要的数据,包括车次,起始站,终点站,起始时间,到达时间,历经时间,当天日期,一等座情况,二等座情况,为了获取数据,用split 对数据分割,储存在数组中方便读取。安装pyecharts,通过pyecharts内置功能实现可视化,为了方便采取了pie(饼图)展示。

实验过程:

  获取url,打开12306网址,F12,打开network,F5刷新一下,找

图中所有的内容,其中Request URL,为我们要使用的URL,

 

 

 

  

找到,Request Headers

里面的Cookie,和User-Agent为头文件内容

 

前期工作结束,开始写代码

 

 

 

import re
利用正则表达式,导入内置模块
import requests

from pyecharts import options as opts
from pyecharts.charts import Page, Pie
pyecharts.charts导入Page,和Pie

为了实现可视化做准备

def send_request():
    url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2022-05-23&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=JNK&purpose_codes=ADULT'
   
headers = {
       
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
        'Cookie': '_uab_collina=165295962817946144015331; JSESSIONID=083B1616F1E4EEE70222E94F0D8EF32E; RAIL_EXPIRATION=1653236462339; RAIL_DEVICEID=nEkhNpJGv6o_j6ljRdO4Oe1tgOLg1k8XxXStB7zs4mypLyvHnmqIlD55NsA4JI_7HWFAHmIJJNoS-MYN3yR5Ie-HadPHNNCpYFyeRjiwN9rcAT4Fjtkzc4-t-T28cQ43dsiQtneda2oykI64g7eYQ9QOcz_BUetW; guidesStatus=off; highContrastMode=defaltMode; cursorStatus=off; _jc_save_fromStation=%u5317%u4EAC%2CBJP; _jc_save_wfdc_flag=dc; _jc_save_toStation=%u6D4E%u5357%2CJNK; _jc_save_toDate=2022-05-21; route=c5c62a339e7744272a54643b3be5bf64; BIGipServerotn=1089470986.24610.0000; BIGipServerpool_passport=149160458.50215.0000; _jc_save_fromDate=2022-05-23'}

   
score = requests.get(url, headers=headers)
   
score.encoding = 'utf-8'
   
return score

提取数据,将响应的数据转化为json,这一步要利用json在线解析,看一下

 

复制一下图上的内容,打开json解析网站

 

在线解析一下,可以看到,数据是以字典的形式储存的,键为data,值为value

值为value也是一个字典,键为result

Map里面为加密的信息,其中“JNK”代表济南等等


def parse_json(score, station):
    json_ticket = score.json()将响应数据转化为json
   
data_lst = json_ticket['data']['result']找到数据中键位date的数据中,键为result的数据
   
tplt = "{0:^14}\t{1:^10}\t{2:^12}\t{3:^12}\t{4:^16}\t{5:^10}\t{6:^16}\t{7:^18}\t{8:^18}"
   
print(tplt.format("车次", "起始站", "终点站", "一等座座位剩余情况", "二等座座位剩余情况", "起始时间", "到达时间", "历经时间", "出行时间")).format
为格式化,以tplt中的进行格式化为了美观

print(
       
'-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------')为了美观分割线
   
car = []
   
site = []
   
site2 = []

 

创建三个数组来存储每次获取的数据,以便进行数据可视化
   
for item in data_lst:
        d = item.split('|')

利用循环遍历所有数据,并用split进行分割


打印了一个数据进行查看,发现这个数组d[3]为车次,d[6]为起始站d[7]为终点站d[31]为一等座剩余情况d[30]为二等座剩余情况d[8]为起始时间d[9]为到达时间d[13]为出行时间d[10]为历经时间
       
car.append(d[3])储存车次

因为12306车票数量大于20张就会显示有,所以我们存储数据的时候,将‘有’赋值为20,‘无’赋值为0,其他的数据直接存储
        if d[31] == '':
            temp = 20
            site.append(temp)
       
elif d[31] == '':
            temp = 0
            site.append(temp)
       
else:
            site.append(d[31])

同理二等座也是这样处理,利用判断语句
       
if d[30] == '':
            temp = 20
            site2.append(temp)
       
elif d[30] == '':
            temp = 0
            site2.append(temp)
       
else:
            site2.append(d[30])
 


       
print('{0:{1}^10}'.format(d[3], chr(12288)), end='')
       
print('{0:{1}^10}'.format(station[d[6]], chr(12288)), end='')
       
print('{0:{1}^10}'.format(station[d[7]], chr(12288)), end='')
       
print('{0:{1}^14}'.format(d[31], chr(12288)), end='')
       
print('{0:{1}^14}'.format(d[30], chr(12288)), end='')
       
print('{0:{1}^14}'.format(d[8], chr(12288)), end='')
       
print('{0:{1}^14}'.format(d[9], chr(12288)), end='')
       
print('{0:{1}^14}'.format(d[10], chr(12288)), end='')
       
print('{0:{1}^10}'.format(d[13], chr(12288)))

这一部分也是为了数据美观,利用format进行格式化
        print(
           
'-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------')
这一部分就是为了实现可视化
   
def pie_rosetype() -> Pie:
        c = (
           
Pie()

第一个pie图标
                .add(
               
"",


                [list(z) for z in zip(car, site)],数据为car[]site[]中的
                radius=["30%", "75%"],内半径,外半径
                center=["25%", "50%"],中心位置
                rosetype="radius",

radius -> list

饼图的半径,数组的第一项是内半径,第二项是外半径,默认为 [0, 75]

默认设置成百分比,相对于容器高宽中较小的一项的一半

center -> list

饼图的中心(圆心)坐标,数组的第一项是横坐标,第二项是纵坐标,默认为 [50, 50]

默认设置成百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度

rosetype -> str

是否展示成南丁格尔图,通过半径区分数据大小,有'radius''area'两种模式。默认为'radius'

radius:扇区圆心角展现数据的百分比,半径展现数据的大小

area:所有扇区圆心角相同,仅通过半径展现数据大小


                label_opts=opts.LabelOpts(is_show=True)这个决定是否显示部分标签,True为显示,False为不显示。

            )
               
.add(
               
"",
                [list(z) for z in zip(car, site2)],
                radius=["30%", "75%"],
                center=["75%", "50%"],
                rosetype="radius",
                label_opts=opts.LabelOpts(is_show=True),
            )

               
.set_global_opts(title_opts=opts.TitleOpts(title="12306 523日车票剩余情况"))set_global_opts 为设置全局配置,这个是设置全局标签,标签为title="12306 523日车票剩余情况"
                .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))部分标签显示格式 {a}(系列名称),{b}(数据项名称)
        )
       
return c

    def page_draggable_layout():
        page = Page(layout=Page.DraggablePageLayout)
       
page.add(

           
pie_rosetype(),

        )
       
page.render("爬虫.html")

创建名字为爬虫.html可视化文件

   
if __name__ == "__main__":
        page_draggable_layout()

__name__其实是一个内置属性,指示当前py文件调用方式的方法。当上述例子运行的时候,整个程序中不管是哪个位置的__name__属性,值都是__main__,当这个hello.py文件作为模块被导入到另一个.py文件中(即import)比如说world.py,并且你运行的是world.py,此时hello.py中的__name__属性就会变成hello,所谓的入口因为if判断失败就不执行了



def start():
    parse_json(send_request(), get_station())


def get_station():
    url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9230'
   
headers = {
       
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36'}
   
score = requests.get(url, headers=headers)
   
score.encoding = 'utf-8'避免乱码
   
stations_name = re.findall('([\u4e00-\u9fa5]+)\|([A-Z]+)', score.text)正则表达式,表示所有的中文和英语
   
stations_name_date = dict(stations_name)
   
stations_name_blank = {}创建空子典,交换keyvalue的值
   
for item in stations_name_date:
        stations_name_blank[stations_name_date[item]] = item
    return stations_name_blank


if __name__ == '__main__':
    start()

同理

 

实验结果:

 

建议

服务器和正则表达式讲的跨度有点大,包括服务器加密,真的搞不懂,在进行实验三的时候,问了很多同学才搞明白大致,做出来。

体会

学了python感觉实现一些想法就比较简单,人生苦短我用python

因为这学期我也在学C语言,相比于C语言,我个人认为,python格式简单,利用方便,但有时候可能正式因为这种简单化,写一些东西就比较难以操作,比如for循环。在同时学习两门语言,有时候写完C语言,再写python,就感觉格式不是很习惯,但是写一段时间就好了。不是很习惯python对字典,集合,数组的赋值和打印读取不是很喜欢。但是对于爬虫来说,python太合适了,相对于c,python

写爬虫很舒服。虽然一学期下来,我对python的学习也仅仅只是它的基础方面,但python的强大,也是足足地吸引着我,希望自己能够在不断地学习中,将python学习的更加好。

全课总结:

学习到了python的基本语法知识,知道了python竟然可以用中文命名,

For,while,循环越用越熟悉了,

知识点

 

List(列表)

List(列表) 是 Python 中使用最频繁的数据类型。

列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。

列表是写在方括号 [] 之间、用逗号分隔开的元素列表。

和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。

 

Tuple(元组)

元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开。

元组中的元素类型也可以不相同:

Set (集合)

 

 

集合(set)是由一个或数个形态各异的大小整体组成的,构成集合的事物或对象称作元素或是成员。

基本功能是进行成员关系测试和删除重复元素。

可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

 

 

Dictionary(字典)

字典(dictionary)是Python中另一个非常有用的内置数据类型。

列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。

字典是一种映射类型,字典用 { } 标识,它是一个无序的 (key) : (value) 的集合。

键(key)必须使用不可变类型。

在同一个字典中,键(key)必须是唯一的。

正则表达式

     数字:^[0-9]*$

     n 位的数字:^\d{n}$

     至少n 位的数字:^\d{n,}$

     m-n 位的数字:^\d{m,n}$

     零和非零开头的数字:^(0|[1-9][0-9]*)$

     非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(\.[0-9]{1,2})?$

     1-2 位小数的正数或负数:

^(\-)?\d+(\.\d{1,2})$

     正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$

     有两位小数的正实数:^[0-9]+(\.[0-9]{2})?$

     1~3 位小数的正实数:

^[0-9]+(\.[0-9]{1,3})?$

     非零的正整数:^[1-9]\d*$

^([1-9][0-9]*){1,3}$ ^\+?[1-9][0-9]*$

     非零的负整数:^\-[1-9][]0-9"*$

^-[1-9]\d*$

     非负整数:^\d+$ ^[1-9]\d*|0$

     非正整数:^-[1-9]\d*|0$ ^((-\d+)|(0+))$

     汉字:^[\u4e00-\u9fa5]{0,}$

     英文和数字:^[A-Za-z0-9]+$ 或^[A-Za-z0-9]{4,40}$

函数

参数的传递、实参、形参

例子+(角色+演员)

参数:数量、位置、要一致,否则要使用关键字参数;默认参数的设置

可变参数:*任意多个,**字典

6.3 返回值、作用域

6.4 匿名函数(lamda)*

匿名函数是指没有名字的函数,应用在需要一个函数,但是又不想去费神命名的场合。通常指使用一次,格式如下:

result = lambda[arg1, [arg2, [arg3, ...., argn]]:expression

result用于调用lamda表达式,是中括号是可选参数(至少一个),expression是必选参数

面向对象

对象:某一个具体的事物、实体或事例

类:具有相同属性和行为的一些对象的统称或集合

面向对象三要素:封装、继承、多态!

 

文件操作及其处理

 

 

 

 

 

 

爬虫开发

10.2 网络爬虫常用技术

(1)网络请求

网络请求有三种模块:Urllib、Urllib3、Requests

①Urllib

它是 Python 内置的 HTTP 请求库,也就是说我们不需要额外安装即可使用,它包含四个模块:

第一个模块 request,它是最基本的 HTTP请求模块,我们可以用它来模拟发送一请求,就像在浏览器里输入网址然后敲击回车一样,只需要给库方法传入 URL还有额外的参数,就可以模拟实现这个过程了。

第二个 error 模块即异常处理模块,如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作保证程序不会意外终止。

第三个 parse 模块是一个工具模块,提供了许多 URL处理方法,比如拆分、解析、合并等等的方法。

第四个模块是 robotparser,主要是用来识别网站的 robots.txt 文件,然后判断哪些网站可以爬,哪些网站不可以爬的,其实用的比较少。

②urllib3

Python2.x 有这些库名可用: urllib,urllib2,urllib3,httplib,httplib2,requests Python3.x 有这些库名可用: urllib,urllib3,httplib2,requests

Python3.x 中将 urllib2合并到了 urllib

 

服务器

利用socket模块建立服务器和客户端

Socket是计算机之间进行网络通信的一套程序接口,相当于在发送端和接收端之间建立了一个通信管道。在实际应用中,一些远程管理软件和网络安全软件大多依赖于Socket来实现特定功能。

 

标签:__,name,format,Python,20212113,python,print,实验报告,opts
来源: https://www.cnblogs.com/zhenhua-qi/p/16319372.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有