Python实训

本文是一篇关于Python编程的实践教程,涵盖了从文件的读写、编码解码、Base64编码,到HTTP请求、正则表达式、BeautifulSoup和XPath解析,再到SQLite数据库和评论情感分析的全程学习。通过实例,读者可以深入理解Python在日常开发中的应用。

第一天:

1. 今日知识大纲

本地文件读写

  1. 读纯文本文件:
  2. 编码解码
  3. 写纯文本文件
  4. With语句
  5. 读非纯文本文件
  6. 写非纯文本文件
  7. Base64编码

 

2. 核心代码

(1)读纯文本文件

# 相对路径   同级./     父级../

# 绝对路径   copy相对路径文件路径

file = open('./chinese_utf8.txt', mode='r', encoding='utf-8')

(2)编码解码

编码方式和解码方式不一样

windows7和早期win10的记事本默认gbk保存

windows10和主流开发工具如pycharm,sublime都是utf-8

大多数中文网站utf-8,少部分gbk

(3)写纯文本文件

#参数mode: r读文本,w写文本,a追加信息,适合日志文件

file = open('./3test.txt', mode='a' ,encoding='utf-8')

file.write('hello world 你好,世界')

# 如果想换行 在‘一行’字符串表达‘换行’的概念,用‘转义’字符

#file.write('hello world \n你好,世界')

file.close()

(4)with语句

# 文件操作和其他某些操作,共性 开始前准备,主要逻辑,收尾工作

# with语句把 开始前准备和收尾工作 抽离自动完成,程序员把主要精力放在逻辑上

with open('./chinese_utf8.txt', mode='r', encoding='utf-8') as f:

    content = f.read()

print(content)

(5)读非文本文件

与with语句相比,重点在于mode模式的不同

#读图片二进制

# mode: r+b b表示二进制模式  删除encoding参数

with open('./testimage.jpg', mode='r+b') as f:

print(f.read())

读是‘r+b’

(6)写非文本文件

写是‘w+b’

(7)base64编码

# 场景:1.字符串方式传播图片。 2.简单加密  3.服务器兼容性

# base64编码作用的是字节

# ‘中’ 00000001 00000001

# base64 00000000 , 0001 0000, 00000001 把真实信息一个字节取36位前面补0,得到几个新的字节,比原始信息大三分之一。

# base64之后每个字节 2的6次方64种可能,对应最简单a-z A-Z -+ 0-9

# 'aF-'

 

# 文本/图片 编码 -> 二进制 -> base64 改变后的二进制 -> ASCII解码成基本字符

 

import base64

 

str1 = '337845818'

content_b64 = base64.b64encode(str1.encode(encoding='utf-8'))

print(content_b64)

#b'MzM3ODQ1ODE4' 本应看到 b'16进制' 只不过是pycharm自动转换了

content_64 = content_b64.decode(encoding='ascii')

print('我的绿色软件是:', content_64)

 

# 图片

with open('./testimage.jpg',mode='rb') as f:

    content_bytes = f.read()

    content_b64_bytes = base64.b64encode(content_bytes)

    content_b64_str = content_b64_bytes.decode(encoding='ascii')

print(content_b64_str)

 

(8)base64解码

import base64

 

# 文本/图片 编码 -> 二进制 -> base64 改变后的二进制 -> ASCII解码成基本字符 逆转过来

 

str1 = 'T3JpZHp1cnU='

str2 = 'MTM3MjUxMDc5NjQ='

 

b64_bytes = str1.encode(encoding='ascii')

print(b64_bytes)

raw_bytes = base64.b64decode(b64_bytes)

print(raw_bytes)

raw_str = raw_bytes.decode(encoding='utf-8')

print(raw_str)

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

第二天:

  1. 今日知识大纲
  1. 图解http
  2. Pip包管理
  3. Requests包应用
  4. Html解析-正则表达式
  5. Html解析-bs库
  6. Html解析-xpath
  1. 核心代码

(3)import requests

 

baidu_index_url = 'https://www.baidu.com'

baidu_search_url = 'https://www.baidu.com/s'

 

headers = {

    #'cookies': '',     #跟公共参数、会话用户有关

    #'referer'" '',     # 从哪个页面来

    # 浏览器标识,容易伪造

    'User-Agent':’Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1'

}

 

params = {

    'wd':'天气',

    'ie':'utf-8'

}

 

response = requests.get(url=baidu_search_url,params=params)

 

status_code = response.status_code

if status_code == 200:

    #网页数据 bytes

    content = response.content

    #网页数据str。一般直接取text属性 但少数情况解码错误乱码

    text = response.text

    text = content.decode('utf-8')  #很少用

    print(text)

    url = response.url

    headers = response.headers

(4)正则表达式

#4中已经用requests模拟请求,拿到源代码,str字符串,里面是HTML格式

#需要解析

#字符串自带的find方法功能有限

html = '<html><body><h1>标题</h1></body></html>'

start_index = html.find('<h1>')

end_index = html.find('</h1>')

print(html[start_index:end_index])

 

#解析方式一:正则regex,专门针对字符串的语法

import re

 

text1 = 'javapythonasdwfdxafwfdaf'

pattern1 = re.compile(r'python')

matcher1 = re.search(pattern1,text1)

print(matcher1[0])

 

text2 = '<h1> hello world</h1>'

pattern2 = re.compile(r'<h1>.+</h1>')

matcher2 = re.search(pattern2,text2)

print(matcher2[0])

(5)bs4

#网页html本身是树状层次结构,按层次去找

#python3适合用beautifulsoup4

from bs4 import BeautifulSoup   # 坑:代码包名字和包元信息不一样

 

html = """

<html>

    <body>

        <a id='ccc' href='https://www.baidu,com'>百度一下</a>

        <a></a>

    </body>

</html>

"""

bs = BeautifulSoup(html,'html.parser')

print(bs.a)

print(bs.find_all('a'))

(6)xpath

from lxml import etree

html = “...”

 

#把长字符串转化为html文档树

dom = etree.HTML(html)

print(dom)

 

# 全文匹配,匹配不到返回[],匹配到返回列表[element,elemrnt]

#语法:/表示下一层  //忽略任意层父级目录

#/body/ul/li/a

print(dom.xpath('//a'))

print(dom.xpath('//ul/li/a'))

#取html元素里的属性

#/@href取元素属性值

print(dom.xpath('//a/@href'))

#取元素内容

# /text()

print(dom.xpath('.//a/text()'))

#属性过滤[@id="second_a"]

print(dom.xpath('.//a[@id="second_a"]/text()'))

 

第三天:

  1. 今日知识大纲
  1. 煎蛋网爬虫
  2. 网易新闻爬虫
  3. Os库
  4. 天堂图片网爬虫
  5. 天堂图片网封装
  1. 核心代码
  1. 煎蛋网爬虫(爬取文本)

#煎蛋网爬虫

import requests

from lxml import etree

 

url = 'http://jandan.net/'

 

headers = {

    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'

}

 

resp = requests.get(url=url,headers=headers)

#print(resp.status_code)

# 403 直接请求 响应码403 有资源但是禁止你访问 加上user-agent

# 304 重定向

if resp.status_code == 200:

    html = resp.text

    #print(html)

    #小技巧:网页想要分析的地方,右键检查,自动定位

    #小技巧:开发者工具elements,ctrl+f打开搜索框,在里面尝试xpath表达式

 

    dom = etree.HTML(html)

    xpath_pattern = '//div[@class="post f list-post"]/div[@class="indexs"]/h2/a/text()'

    titles = dom.xpath(xpath_pattern)

    #print('titles',titles)

 

    for i in titles:

        print(i)

  1. 天堂图片网(爬取图片)

# 天堂网爬虫

import os

import  requests

from lxml import etree

 

# home_url = 'https://www.ivsky.com/'

# catalog_url = ''

album_url = 'https://www.ivsky.com/tupian/lugui_v62472/'

 

headers = {

    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'

}

 

# 请求网集页

resp = requests.get(album_url)

status_code = resp.status_code

#print(status_code)

album_html = resp.text

#print(album_html)

 

#获取一个图集下所有缩略图片的url地址

album_dom = etree.HTML(album_html)

title_pattern = '//h1/text()'

img_pattern = '//ul[@class="pli"]/li/div/a/img/@src'

album_title = album_dom.xpath(title_pattern)[0]

album_title = album_title.strip()# 图集名

img_src_list = album_dom.xpath(img_pattern)

#print(album_title)     # 输出图集名称

#print(len(img_src_list),img_src_list)      #输出图片url

 

# 用图集名创建文件夹

if not os.path.exists('./'+album_title):        #' 体型庞大的陆龟照片

    os.mkdir('./'+album_title)

 

# 循环图片地址列表,请求每一张图片

for i,img_src in enumerate(img_src_list):

    # 拼完整图片url

    img_src = 'https:'+img_src  # url切片

    print(img_src)

    resp = requests.get(img_src,headers=headers)

    #print(resp.status_code)

    img_content_bytes = resp.content

 

    # 图片二进制信息写入本地

    img_path = os.path.join(os.path.dirname(__file__),album_title,f'{i+1}.jpg')

    print(img_path)

    with open(img_path,mode='wb') as f:

        f.write(img_content_bytes)

        print(f'图片{i+1}写入成功,保存到了{img_path}')

 

第四天:

  1. 今日学习大纲
  1. 动态网页和静态网页

# 区分:如果网页的doc界面的html和elements的一样就是静态网页

#       在network中的js xhr中分析

  1. Json格式
  2. 评论请求寻找分析

# 找js xhr请求评论数据

# 不关心对方js怎么写的和渲染的网页。只要找到http请求,用python来模拟

# 寻找技巧:

# 1. 开发者工具network,过滤xhr和js的请求

# 2. 找post类型的http请求

# 3. 找比较像的名字 comment api get_info get_list

# 4. 响应的是纯数据,不是HTML信息

# 5. 尝试在网页中触发异步js请求,在开发者工具中观察变化

# 6. network工具获取焦点,ctrl+f打开隐藏的搜索框,在所有请求,请求头,响应全文搜索关键字。

  1. 请求天气接口
  2. 请求京东评论接口
  1. 核心代码
  1. json格式

import json

# json 字符串 -> python内置数据结构

xiaoming_dict = json.loads(xiaoming_json_str)

# json.load(本地文件.json)

 

# PYTHON内置数据结构 -> json字符串

students = [

    {'name':'ming','age':13,'gender':'m'},

    {'name':'hong','age':12,'gender':'wm'}

]

students_json = json.dumps(students)

print(type(students_json),students_json)

 

  1. 请求京东评论接口

import json

import requests

 

base_url = 'https://club.jd.com/comment/productPageComments.action'

 

# 本次请求头只用伪造user-agent即可,但是前端时间测试需要cookie字段

headers = {

    #'Cookie' :'__jdu=1610951435695866394438',

    #'Referer': 'https://item.jd.com/',

    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'

}

 

# 从请求头下面的query parama复制下来再调整,使用编辑器模式,alt+shift+鼠标拖动(多光标)

params = {

    #'callback': 'fetchJSON_comment98',  #

    'productId': 100009077475,  #商品id

    'score': 0,

    'sortType': 5,

    'page': 1,                  #第几页

    'pageSize': 10,             #一页的个数

    'isShadowSku': 0,

    'rid': 0,

    'fold': 1

}

 

resp = requests.get(base_url,headers=headers,params=params)

status_code = resp.status_code

comment_json = resp.text

#print(comment_json)

# 京东评论接口返回jsonp格式,涉及跨域问题  需将jsonp转化为json

# 方法1:python字符串方法删除固定长度无用字符串

# 方法2:从网上找从jsonp过滤json正则

 

comment_obj = json.loads(comment_json)

#print(comment_obj)

comments = comment_obj['comments']

for c in comments:

    #print(c)

    cid = c['id']

    content = c['content']

    creation_time = c['creationTime']

    images = c['images']

    product_color = c['productColor']

    product_size = c['productSize']

    print('-'*100)

print(cid,content)

(5)注意:请求接口时,要找出对应的json文件对比


第五天:

  1. 今日学习大纲
  1. sqlite数据库
  2. 京东爬虫数据库版
  3. jieba分词
  4. 停止词
  1. 核心代码

京东爬虫数据库版

import json

import sqlite3

import time

import requests

 

def get_one_product_one_page_comments(pid, pageno=1):

    base_url = 'https://club.jd.com/comment/productPageComments.action'

 

    # 本次请求头只用伪造user-agent即可,但前端时间测试需要cookie字段

    headers = {

        # 'Cookie': '__jdu=16096534364451068756302;',

        # 'Referer': 'https://item.jd.com/',

        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',

    }

 

    # tips:从开发者工具network请求头下面的query params复制下来再调整。使用编辑器列编辑模式 alt+shift+鼠标拖动。

    params = {

        #'callback': 'fetchJSON_comment98',

        'productId': pid,  # 商品id

        'score': 0,

        'sortType': 5,

        'page': pageno,                  # 第n页  经测试最大99页,之后只有概括数据无详细数据。

        'pageSize': 10,

        'isShadowSku': 0,

        'rid': 0,

        'fold': 1

    }

 

    # for i in range(1, 20):

    #   params['page'] = i

    resp = requests.get(base_url, headers=headers, params=params)

    status_code = resp.status_code

    comments_json = resp.text

    #print(comments_json)

    # 京东评论接口返回jsonp格式,涉及跨域问题。需要将先jsonp转json。

    # 方法1:python字符串方法删除固定长度无用字符串;2(推荐)上网找从jsonp过滤json正则;3本例中发现修改参数可以直接返回json

 

    comments_obj = json.loads(comments_json)

    #print(comments_obj)

    comments = comments_obj['comments']

    return comments

 

def write_comment_to_db(c, cursor):

    cid = c['id']

    content = c['content']

    creation_time = c['creationTime']

    images = c.get('images', None)

    product_color = c['productColor']

    product_Size = c['productSize']

 

    # 一条评论写入数据库

    cursor.execute("""

        insert into comments (cid, content, product_color, creation_time)

        values (?, ?, ?, ?);

    """, [cid, content, product_color, creation_time])

 

def db_init():

    # 数据库初始化

    connect = sqlite3.connect('./jd.db')

    cursor = connect.cursor()

    cursor.execute("""

            CREATE TABLE IF NOT EXISTS comments(

            id INTEGER PRIMARY KEY,

            cid INTEGER,

            content TEXT,

            product_color TEXT,

            creation_time DATETIME

        );

        """)

 

if __name__ == '__main__':

    db_init()

    #connect = sqlite3.connect('./jd.db')

    #cursor = sqlite3.connect('./jd.db').cursor()

 

    product_id = 100009077475

    for pageno in range(1, 3):

 

        one_page_comments = get_one_product_one_page_comments(product_id, pageno)

        for c in one_page_comments:

            write_comment_to_db(c, cursor)

        connect.commit()

        print(f'第{pageno}页数据插入完成')

        time.sleep(1)

connect.close()

 

第六天:

  1. 今日学习大纲

  1. 估算评论情感分数
  2. 词云图
  1. 核心代码

词云图

# 常用:pillow

# coding:utf-8

 

import jieba

import sqlite3

from wordcloud import WordCloud

 

connect = sqlite3.connect('../L05数据持久化和清洗/jd.db')

cursor = connect.cursor()

cursor.execute("""select * from comments order by creation_time desc limit 1,10;""")

comments_rs = cursor.fetchall()

comments = [c[2] for c in comments_rs]

comments = ''.join(comments)

#print(comments)

 

words = jieba.cut(comments,cut_all=False)

comment_words = [w for w in words]

#print(comment_words)

 

#comment_words_str = ' '.join(comment_words)

# print(comment_words_str)

 

comment_words_after = []

with open('./dict/stop_words_zh.txt',mode='r',encoding='utf-8') as f:

        stop_words = f.read().splitlines ()

        for comment_word in comment_words:

            if comment_word not in stop_words:

                comment_words_after.append(comment_word)

        #print(comment_words_after)

        comment_words_str = ' '.join(comment_words_after)

 

font = './STXINWEI.TTF'

wc = WordCloud(font_path=font,

        background_color='white',

        width=1000,

        height=800,

        min_font_size=50,

        ).generate(comment_words_str)

wc.to_file('./2评论词云图.png')

 

 

第七天:

进行项目总结。

 

 

 

 

 

 

撰写一份结构清晰、内容完整的 Python 实训报告,通常应包括以下几个核心部分:实训目的与要求、实训环境、实训内容与步骤、代码实现、运行结果、问题分析与总结等。以下是一个通用的模板和示例指导。 ### ### 一、实训报告基本结构 #### 1. 实训题目 简明扼要地写出本次实训的主题或项目名称。 #### 2. 实训目的与要求 说明本次实训的目标,例如掌握某个知识点、完成某项功能开发、熟悉某种工具使用等。 - 掌握Python基础语法及数据处理方法。 - 熟悉requests库进行网页数据抓取。 - 学会使用json模块解析和生成JSON格式数据[^4]。 #### 3. 实训环境 列出所使用的操作系统、编程语言版本、开发工具、第三方库等。 - 操作系统:Windows 10 / macOS / Linux - 编程语言:Python 3.9 - 开发工具:PyCharm / VS Code / Jupyter Notebook - 第三方库:requests, beautifulsoup4, pandas, json #### 4. 实训内容与步骤 详细描述实训任务的流程,可结合流程图或伪代码说明整体逻辑。 - 使用requests发起GET请求获取网页内容。 - 利用BeautifulSoup解析HTML页面,提取目标数据。 - 将爬取的数据整理为结构化形式(如字典或DataFrame)。 - 使用pandas将数据保存为CSV文件。 #### 5. 代码实现 提供完整或关键部分的代码,并附上必要的注释。 ```python import requests from bs4 import BeautifulSoup import pandas as pd url = "https://example.com" response = requests.get(url) soup = BeautifulSoup(response.text, 'html.parser') data = [] for item in soup.find_all('div', class_='item'): title = item.find('h2').text desc = item.find('p').text data.append({'title': title, 'description': desc}) df = pd.DataFrame(data) df.to_csv('output.csv', index=False) ``` #### 6. 运行结果 展示程序执行后的输出截图或文本结果,说明是否达到预期效果。 - 控制台输出日志信息。 - 成功生成output.csv文件。 - 文件中包含从网页抓取的标题与描述字段。 #### 7. 问题分析与解决 记录实训过程中遇到的问题及解决方案。 - **问题**:网页编码不一致导致中文乱码。 - **解决**:在requests.get()后添加`response.encoding = response.apparent_encoding`以自动识别编码方式。 #### 8. 实训总结 总结本次实训的收获、体会以及改进建议。 - 对Python网络爬虫的基本流程有了更深入理解。 - 掌握了如何使用第三方库高效提取和存储数据。 - 后续可尝试引入Scrapy框架提升爬虫效率与扩展性。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值