python简单爬取网页内容

  1. 了解网页;
  2. 使用 requests 库抓取网站数据;

网页结构

网页一般由三部分组成,分别是 HTML(超文本标记语言)、CSS(层叠样式表)和 JScript(活动脚本语言)。

合法性

几乎每一个网站都有一个名为 robots.txt 的文档,当然也有部分网站没有设定 robots.txt。对于没有设定 robots.txt 的网站可以通过网络爬虫获取没有口令加密的数据,也就是该网站所有页面数据都可以爬取。如果网站有 robots.txt 文档,就要判断是否有禁止访客获取的数据。

安装requests(Windows)

  1. python安装
  2. 在命令提示符下输入:pip3 install requests
  3. 验证是否安装成功
  4. 主要使用IDLE进行学习
import requests
r = requests.get("https://www.baidu.com")
r.status_code
r.encoding = 'utf-8'
r.text

网页分析python代码 python网页结构分析_html


网页分析python代码 python网页结构分析_json_02

请求过程

  1. Request (请求):每一个展示在用户面前的网页都必须经过这一步,也就是向服务器发送访问请求。
  2. Response(响应):服务器在接收到用户的请求后,会验证请求的有效性,然后向用户(客户端)发送响应的内容,客户端接收服务器响应的内容,将内容展示出来,就是我们所熟悉的网页请求

请求方式

  1. GET:最常见的方式,一般用于获取或者查询资源信息,也是大多数网站使用的方式,响应速度快。
  2. POST:相比 GET 方式,多了以表单形式上传参数的功能,因此除查询信息外,还可以修改信息。

学会使用Google检查功能

网页分析python代码 python网页结构分析_数据_03


这里分享一下早期学习的一个得到LOL皮肤图片的成果

import requests
import json
from urllib import parse
import os


class GetLolSkin(object):
    """抓取LOL英雄皮肤"""

    def __init__(self):
        """初始化变量"""
        self.hero_url = 'https://lol.qq.com/biz/hero/champion.js'
        self.hero_detail_url = 'http://lol.qq.com/biz/hero/'
        self.skin_folder = 'skin'
        self.skin_url = 'https://ossweb-img.qq.com/images/lol/web201310/skin/big'

    @staticmethod
    def get_html(url):
        """下载html"""
        request = requests.get(url)
        request.encoding = 'gbk'
        if request.status_code == 200:
            return request.text
        else:
            return "{}"

    def get_hero_list(self):
        """获取英雄的完整信息列表"""
        hero_js = self.get_html(self.hero_url)
        # 删除左右的多余信息,得到json数据
        out_left = "if(!LOLherojs)var LOLherojs={};LOLherojs.champion="
        out_right = ';'
        hero_list = hero_js.replace(out_left, '').rstrip(out_right)
        return json.loads(hero_list)

    def get_hero_info(self, hero_id):
        """获取英雄的详细信息"""
        # 获取js详情
        detail_url = parse.urljoin(self.hero_detail_url, hero_id + '.js')
        detail_js = self.get_html(detail_url)
        # 删除左右的多余信息,得到json数据
        out_left = "if(!herojs)var herojs={champion:{}};herojs['champion'][%s]=" % hero_id
        out_right = ';'
        hero_info = detail_js.replace(out_left, '').rstrip(out_right)
        return json.loads(hero_info)

    def download_skin_list(self, skin_list, hero_name):
        """下载皮肤列表"""
        # 循环下载皮肤
        for skin_info in skin_list:
            # 拼接图片名字
            if skin_info['name'] == 'default':
                skin_name = '默认皮肤'
            else:
                if ' ' in skin_info['name']:
                    name_info = skin_info['name'].split(' ')
                    skin_name = name_info[0]
                else:
                    skin_name = skin_info['name']
            hero_skin_name = hero_name + '-' + skin_name + '.jpg'
            self.download_skin(skin_info['id'], hero_skin_name)

    def download_skin(self, skin_id, skin_name):
        """下载皮肤图片"""
        # 下载图片
        img_url = self.skin_url + skin_id + '.jpg'
        request = requests.get(img_url)
        if request.status_code == 200:
            print('downloading……%s' % skin_name)
            img_path = os.path.join(self.skin_folder, skin_name)
            with open(img_path, 'wb') as img:
                img.write(request.content)
        else:
            print('img error!')

    def make_folder(self):
        """初始化,创建图片文件夹"""
        if not os.path.exists(self.skin_folder):
            os.mkdir(self.skin_folder)

    def run(self):
        # 获取英雄列表信息
        hero_json = self.get_hero_list()
        hero_keys = hero_json['keys']
        # 循环遍历英雄
        for hero_id, hero_code in hero_keys.items():
            hero_name = hero_json['data'][hero_code]['name']
            hero_info = self.get_hero_info(hero_id)
            if hero_info:
                skin_list = hero_info['result'][hero_id]['skins']
                # 下载皮肤
                self.download_skin_list(skin_list, hero_name)
            else:
                print('英雄【%s】的皮肤获取有问题……' % hero_name)


# 程序执行入口
if __name__ == '__main__':
    lol = GetLolSkin()
    # 创建图片存储文件
    lol.make_folder()
    # 执行脚本
    lol.run()