1 Star 0 Fork 0

Kazin / GameCrawler_4399

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

4399小游戏上的Python爬虫

主讲:陈家仁

所属:景德镇陶瓷大学移动互联协会

项目已上传至:https://gitee.com/kazin/GameCrawler_4399

[TOC]

Stage1 Python的环境配置

1. 代码编辑器 Pycharm community

2. 代码解释器 Python 3.7.6

  • 安装时勾选Add To PATH

    环境变量

    • ​ 根据作用域分为用户级和系统级
      1. 用户级:对当前用户有效
      2. 系统级:对所有用户有效
    • 实用工具
      1. 任务管理器:taskmgr
      2. 控制面板:control
      3. 计算器:calc
      4. 画图:mspaint
      5. 1S后关机:shutdown -s -t 1
      6. 取消关机任务:shutdown -a
  • 启动Python交互式编程:运行命令py(或者python)

3. 在Pycharm中创建项目并配置Python环境

  • Base Interpreter 填写Python的安装目录
  • 虚拟环境:使得不同项目的包可以相互独立,互不干涉

4. 安装工具包的两种方式

  1. Pycharm内部安装

  2. pip命令安装

    pip list 输出所有安装在当前环境的工具包

    pip install packageName 安装工具包

    pip uninstall packageName 卸载工具包

    ​ 更换pip下载源

    1. 临时 pip install packageName -i https://pypi.tuna.tsinghua.edu.cn/simple

    2. 长期更换

      1. step1:在用户目录下创建pip文件夹

      2. step2:在pip文件夹下创建pip.ini配置文件

      3. step3:在pip.ini配置文件中写入:

        [global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple [install] trusted-host=mirrors.aliyun.com

    项目创建后最好不要更改名称,否则可能会遇到意想不到的错误

Stage2 Python 基本知识

1. 编程方式

  • 交互式

    写一句执行一句, 主要用于代码测试

  • 脚本式

    批量执行脚本内的语句, 且编写的代码可以保存

2. 基本语法

  1. print()输出变量的值

  2. 变量和标识符 # 表示单行注释,解释器会忽略注释

  3. 使用Ctrl+Alt+L快捷键进行代码格式化,除中文外所有符号都应是英文半角状态

  4. 变量类型

    1. int 整型 ( 整数类型 )

    2. str 字符串 使用''""括起,例:'hello'"world"

    3. list 列表,

      • 下标从0开始, 元素之间使用,分隔

        list1 = ['a', 'b', 'c']
        print(list1[1]) #输出 b
      • 添加元素, 使用.append()方法

        list1.append('d')
        print(list1) # 输出['a', 'b', 'c', 'd']
      • 修改元素

        dict1 = {"姓名": "张三", "专业": "信息管理与信息系统"}
        list1[1] = dict1 # 字典与列表嵌套
        print(list1[1]) # 输出{"姓名": "张三", "专业": "信息管理与信息系统"}
    4. dict 字典(元素为键值对)

      • 键为字符串, 通过键可以得到值

        dict1 = {"姓名": "张三", "专业": "信息管理与信息系统"}
        print(dict1["姓名"]) # 输出 张三
      • 修改/添加元素

        dict1['姓名'] = '李四' # 键已存在, 则修改原值
        dict1['年级'] = '2018级' # 键不存在,则创建并添加新的键值对
  5. 字符串连接运算符+

    print('hello ' + 'world') #输出 hello world
  6. 条件判断

    1. 布尔类型 ( boolean ) , 只有两个值:TrueFalse

    2. 关系运算 ( 结果为布尔类型 )

      1. 等值判断== (只有一个等号=是赋值运算符)

        a = 'hi' # 赋值
        print(a == 'hello') # 输出False
      2. 关系运算符

        运算符 含义 运算符 含义
        != 不相等 == 相等
        < 小于 > 大于
        <= 小于等于 >= 大于等于
    3. if - elif - else 语句( 符合条件就执行:后的子层代码 )

      elif 是 else if的缩写

      python中使用缩进 ( tab )表示层级关系

      grade = 73
      if grade >= 80:
          print('优')
      elif grade >= 60:
          print('及格')
      else:
          print('不及格')
      # 输出 及格
  7. 循环与遍历

    1. 循环: 只要满足条件就继续执行
    2. 遍历: 使用序列的每一个元素, 最后一个元素使用完时遍历结束
    # 循环
    count = 0
    while count < 5:
        print(count)
        count += 1 # 等价于 count = count + 1
    # 遍历
    for i in range(0,5):
    	print(i)
    
    # 上述循环和遍历都输出 0 1 2 3 4
  8. 函数

    1. 使用def关键字定义

      def functionName(): # 定义函数
          print('hello world')
      
      functionName() # 调用函数functionName
    2. 带参数的函数

      def add(x,y): # x,y为参数
          result = x + y
          return result # 将结果返回到函数调用处
      sum = add(3,5) # 调用函数的同时传递参数, add函数的返回值赋值给sum
      print(sum) # 输出 8
    3. 关键字参数

      def hello(name='defaultName'):
          print('hello ' + name)
      hello() # 输出 hello defaultName
      hello(name='cjr') # 输出 hello cjr
  9. 异常

    • 当语法正确的程序运行发生错误时, 会抛出异常

    • 使用try-except结构捕捉异常并进行处理

      try:
          print(5 / 0)
      except ZeroDivisionError:
          print('0不能作除数')
  10. 导入工具包 ( 包中的.py文件称为: 模块module )

    from random import randint as rd #从random模块中导入randint函数, 并命名为rd
    print(rd(1,6)) # 模拟掷骰子得到的点数

    小实例: 使用MyQR或qrcode来生成二维码

    Ctrl+p展开函数参数信息

    Alt+Enter展开编辑器建议

    #方法一 不支持中文, 可生成个性化二维码图片
    from MyQR import myqr
    massage = 'I am the information behind of the QRC'
    myqr.run(word=massage,save_name='我创建的二维码.png',picture='陶大移协.gif',colorized=True,version=5,level='H')
    massage = 'https://www.baidu.com'
    myqr.run(word=massage,save_name='链接二维码.png')
    '''
    参数说明
    level:字符串类型,控制纠错水平,范围是L、M、Q、H,从左到右依次升高
    picture:字符串类型,图片链接,支持png、jpg、bmp、gif(用gif格式的话,生成的二维码就是动态的)
    colorized:值为False则是黑白色
    picture: 背景图片的位置
    version: 生成二维码的大小,值越大越清晰,耗时越长
    '''
    
    # 方法二
    from qrcode import main
    qrc = main.QRCode()
    qrc.add_data('我是隐藏在二维码后的信息')
    qrc.make_image().save('test.png')
  11. 多线程

    用于并发执行任务

    import threading
    
    import requests
    from string import ascii_letters as letters
    from random import sample
    
    # 定义一个用于执行下载任务的函数
    def download(downloadUrl='https://www.baidu.com/favicon.ico', count=0, folder='./'):
        filePath = folder + ''.join(sample(letters, 5)) + '.ico'
        with open(filePath, 'wb') as file:
            # 将下载的内容保存到硬盘上
            file.write(requests.get(downloadUrl).content)
            print(str(count) + '号任务下载完成!已保存在' + filePath)
    
    
    url = 'https://csdnimg.cn/public/favicon.ico'
    # 常规下载
    # print('开始下载文件')
    # for i in range(0, 20):
    #     download(url, i, './normalDownload/')
    # print('所有下载任务完成')
    
    # 多线程下载
    print('开始分配下载任务')
    for i in range(0, 20):
        threading.Thread(target=download, args=(url, i,'./multiThreadDownload/')).start()  # 启动匿名线程, 并传递参数
    print('下载任务已分配完成')

    元组tuple

    list11 = ['a','b','c'] # 列表可以对元素进行修改
    tuple1 = tuple(list1) # 将列表冻结为元组, 冻结后所有元素不能更改, 如需更改先解冻(转换为list类型)
    print(tuple1) # 输出 ('a','b','c')
    list2 = list(tuple1) # 将tuple2解冻后赋值给list2

Stage3 4399小游戏爬虫实战

1. 爬虫的基本步骤

1. 使用requests下载网页
2. 使用BeautifulSoup将requests下载的内容解析为DOM (文档对象模型) 
3. 通过DOM获取所需要的数据

2. 4399小游戏的本地运行

  1. 支持下载到本地的游戏 : 以 .swf 为扩展名的游戏

  2. 游戏主体页的的src属性可以得到绝对地址

    游戏绝对地址示例: http://sxiao.4399.com/4399swf/upload_swf/ftp29/liuxinyu/20190731/7/main.swf

  3. 游戏信息页可以获取相对地址: 在<script>标签中 , Ctrl+F 搜索关键字 _strGamePath可以得到

    游戏相对地址示例: /upload_swf/ftp29/liuxinyu/20190731/7/main.swf

  4. 所需文件: 爱奇艺万能播放器 ( 已更名为万能联播 ) ( GeePlayer.exe )

image-20200420124923182

3. 4399小游戏爬虫实现思路

  1. 爬取4399好玩的小游戏页面, 通过解析得到DOM来获取所有的游戏链接
  2. 遍历所有的游戏链接, 开启线程下载该链接的网页并判断该游戏是否支持下载到本地, 如果支持则拼接下载地址, 并开启游戏下载线程
  3. 游戏下载线程: 根据下载地址来下载 .swf 文件并保存到本地

完整代码

import os
import re
import threading

from bs4 import BeautifulSoup as bs
import requests


def getAllGameUrl():
    """
    获取所有游戏的名称和游戏信息页的链接
    :return:
    """
    gameUrlList = []
    response = requests.get('http://www.4399.com/flash/gamehw.htm')
    dom = bs(response.content, 'html.parser')
    gameLiList = dom.select('#skinbody > div:nth-child(6) > ul > li')
    for i in gameLiList:
        # 获取游戏的名称
        gameName = i.select_one('a > b').get_text()
        # 获取游戏信息页的链接
        # 'http://www.4399.com/flash/212103.htm'
        gameInfoUrl = indexUrl + i.select_one('a')['href']
        gameUrlList.append({'gameName': gameName, 'gameInfoUrl': gameInfoUrl})
    return gameUrlList


def downloadIfAvailable(game):
    """
    判断一个游戏是否支持本地下载
    :return:
    """
    response = requests.get(game['gameInfoUrl'])
    plainText = response.text
    relativeUrlList = re.findall(r'(?<=_strGamePath=").+?\.swf', plainText)
    if len(relativeUrlList) != 0:
        gameUrl = gameBaseUrl + relativeUrlList[0]
        game['gameUrl'] = gameUrl
        threading.Thread(target=downloadAGame, args=(game,)).start()


def downloadAGame(game):
    """
    根据下载链接下载游戏,并保存到.swf文件
    :param game:
    :return:
    """
    downloadPath = 'games/'
    if not os.path.exists(downloadPath):
        try:
            os.mkdir(downloadPath)
        except FileExistsError as e:
            print(e)
    with open(downloadPath + game['gameName'] + '.swf', 'wb') as file:
        file.write(requests.get(game['gameUrl']).content)
        print(game['gameName'] + '下载完成')


if __name__ == '__main__':
    indexUrl = 'http://www.4399.com'
    gameBaseUrl = 'http://sxiao.4399.com/4399swf'
    gameUrlList = getAllGameUrl()
    for i in gameUrlList:
        threading.Thread(target=downloadIfAvailable, args=(i,)).start()

空文件

简介

暂无描述 展开 收起
Python
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Python
1
https://gitee.com/kazin/GameCrawler_4399.git
git@gitee.com:kazin/GameCrawler_4399.git
kazin
GameCrawler_4399
GameCrawler_4399
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891