zoukankan      html  css  js  c++  java
  • Python10 前端基础与爬虫

    Python10 ---- 前端基础与爬虫

    前端基础与爬虫

    一个请求的组成

    def request_jd(keyword):
        url = "https://search.jd.com/Search"
        params = {
            "keyword": keyword
        }
        headers = {
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"
        }
        response = requests.get(url=url, params=params, headers=headers)
        response.text  获取str类型的响应内容
        response.content 获取bytes类型的响应内容
        response.json() 获取json格式数据
    • 请求行(request line)

      • URL
      • 请求方法(method)
    • 请求头(headers)

      • user-agent
        用来指示当前请求时从哪个终端发起的

      • cookie
        用来指示当前的用户信息和行为信息

    • 请求体(body)

      • params(严格来说不算是请求体)
        实际请求的时候会变成URL的一部分, 所以说post请求也可以用params

        • urlencode和urldecode
          请求头中指定的编码格式只对请求体是有效的, 不对params有效. 所以urlencode来保证URL不会发生编码问题.
          from urllib.parse import quote, unquote
          
          print(quote("鼠标"))
          print(unquote("%E9%BC%A0%E6%A0%87"))
      • data
        携带额外的请求信息.

    静态页面和动态页面

    • 静态页面
      纯粹的HTML文件, 简单地说当前的页面文件就存储在服务端, 我们请求的静态页面实际上就是请求对方服务器中的文件. 通过返回不同的HTML文件来完成不同请求的显示效果.

      • 动态页面和静态页面的区分绝不是指页面上的动画效果

      最见的就是各大企业网站

    • 动态页面
      动态页面是指除了HTML以外, 通过ajax在不直接刷新页面的前提下, 完成了和服务端的数据交互. 并通过javascript回调函数完成对页面内容的修改, ajax和服务端交互的数据格式通常为json

      浏览商品

      视频网站的瀑布流

      • Ajax

        asynchronous JavaScript-XML 异步javascript和xml的缩写

        在不直接刷新页面的前提下, 完成了和服务端的数据交互. 并通过javascript回调函数完成对页面内容的修改, ajax和服务端交互的数据格式通常为json.

      • json
        js对象标记法, 用来表示对象关系

        js中的对象: {a: 1, b: null}

        • json的作用
          是一种跨平台跨语言的传输对象格式, 可以保留一些基础的数据类型信息.

          原来json只是作为前端和服务端传输数据的格式规范, 但是现在几乎所有热门语言都内置了json, 所以可以称之为跨语言的传输格式

        import json
        
        test_dict = {
            "a": 1,
            "b": ["1", 2, None],
            "c": {"d": 1}
        }
        
        # json格式数据其实是个字符串
        # 将python字典转变为json数据格式
        json_data = json.dumps(test_dict)
        print(type(json_data), json_data)
        
        # 将json数据格式转变为字典
        print(json.loads(json_data))

    HTML, CSS和JS

    html和js决定了显示的内容, css决定了怎么显示.

    • HTML(HyperTextMarkup Language 超文本标记语言)

      • HTML的作用
        定义网页的内容的含义和结构.
        • tag(标签)
          <标签名>

          • <html>
            表示当前是一个HTML文档对象

          • <head>
            提供一些基础信息

            # 通过meta标签来表示当前页面的编码格式
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
          • <body>
            纯内容

        • element(元素)
          <标签名> xxxxxxxxxx</标签名>

    • CSS(Cascading Style Sheets 层叠样式表)

      能对网页中的元素位置的排版进行像素级别的控制. 页面的渲染主要就是通过css来完成的.

    • JavaScript
      通过<script></script>包裹, 主要完成数据的交互和对DOM树(HTML是一个结构化的数据文件, DOM就是将结构化的数据转变成对象)的修改.

    浏览器渲染的过程

    • 接收到HTML文件后开始构建DOM(Doucment Object Model)树.
    • CSS来计算DOM树各个节点的坐标, 大小等CSS属性, 开始布局.
    • 开始加载媒体资源和页面渲染.

    课后作业

    • 完成京东搜索页面的请求并保存为HTML格式文件(10个即可, 请求频繁容易被封)
      f = open("search_keyword.html", "w", encoding="utf-8")
    • 完成京东详情页面的请求并保存为HTML格式文件(10个即可, 请求频繁容易被封)
    import requests
    # 请求头中指定的编码格式只对请求体是有效的, 不对params有效. 所以urlencode来保证URL不会发生编码问题.
    
    def request_jd(keyword):
        url = "https://search.jd.com/Search"
        params = {
            "keyword": keyword
        }
        # 请求头
        headers = {
            # 指客户端使用什么软件访问,或发起的
            # cookice 用户或设备的身份信息,仅有真实的身份才会有cookice
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"
        }
        # 请求体 params严格说不属于请求体,而data是,可以携带额外的请求信息.
        response = requests.get(url=url, params=params, headers=headers)
        # response.text  # 获取str类型的响应内容
        # response.content #获取bytes类型的响应内容 #有乱码可调试
        # response.json()  # 获取json格式数据
        result = response.text
        # print(result)
        file_name = keyword
        with open(f'search_keyword_{file_name}.html', "w", encoding="utf-8") as f:
            f.write(result + "\n")
    
    
    if __name__ == '__main__':
        task_array = ["鼠标", "键盘", "显卡", "耳机"]
        for i in task_array:
            request_jd(i)
        # request_jd('鼠标')
    • 练习python中json库的使用
    import json
       
       test_dict = {
           "a": 1,
           "b": ["1", 2, None],
           "c": {"d": 1}
       }
       
       # json格式数据其实是个字符串
       # 将python字典转变为json数据格式
       json_data = json.dumps(test_dict)
       print(type(json_data), json_data)
       
       # 将json数据格式转变为字典
       print(json.loads(json_data))

    css-selector

    尽量避免解析路径中包含位置信息
    chrome页面中内置了Jquery环境, 用$符号来表示

    • 直接定位元素

      • 通过id进行定位

        $("#id值")
      • 通过class进行定位

        $(".class值")
      • 通过属性名进行定位

        $("标签名[属性名='属性值']")
        
        $("ul[class='gl-warp clearfix']")
    • 获取兄弟节点

      • 获取当前节点的下一个节点

        • dom提供的接口, 不属于css-selector语法

          tmp = $("li[data-sku='6039832']")[0]
          tmp.nextElementSibling
        • 通过css-selector(不建议)

          $("ul[class='gl-warp clearfix'] li:first-child + li")
      • 获取当前节点的上一个节点

        • dom提供的接口, 不属于css-selector语法
          tmp = $("li[data-sku='2136538']")[0]
          tmp.previousElementSibling
    • 获取父子节点

      • 获取父节点

        • dom提供的接口, 不属于css-selector语法

          tmp.parentElement
      • 获取子节点

        • 获取所有子节点

          • 遍历所有符合条件的元素

            $("ul[class='gl-warp clearfix'] div[class='gl-i-wrap']")
          • dom提供的接口, 不属于css-selector语法

            $("ul[class='gl-warp clearfix']")[0].children
        • 获取第一个子节点

          :fist-child
          $("ul[class='gl-warp clearfix'] li:first-child")[0]
        • 获取最后一个子节点

          :last-child
          $("ul[class='gl-warp clearfix'] li:last-child")[0]
        • 获取第N个子节点

          :nth-child(索引)
          $("ul[class='gl-warp clearfix'] li:nth-child(5)")[0]
    • 模糊匹配

      • 匹配开头
        ^

        # 匹配data-sku属性值为2开头的元素
        $("li[data-sku^='2']")
      • 匹配结尾
        $

        $("li[data-sku$='2']")
      • 匹配子集

        *

        $("li[data-sku*='2']")
    • 获取文本值

      $("li[data-sku='6039832'] div[class='p-name p-name-type-2'] em")[0].innerText
    • 获取属性值

      $("ul[class='gl-warp clearfix'] li")[0].getAttribute("data-sku")

    BeautifulSoup

    • 安装

      pip install bs4
      pip install lxml
    • 使用BeautifulSoup

      from bs4 import BeautifulSoup
      
      
      def jd_search_parse(html):
          soup = BeautifulSoup(html, "lxml")
          item = soup.select("li[data-sku='6039832']")[0]
    • 直接定位元素
      略,因select已经满足当前定位的需求了

    • 去除空白字符

      html = html.replace('\r\n', "").replace("\n", "").replace("\t", "")
    • 获取兄弟节点

      • 获取上一个节点

        tmp_ele.previous_sibling
      • 获取下一个节点

        tmp_ele.next_sibling
    • 获取父子节点

      • 获取父节点

        tmp_ele.parent
      • 获取子节点

        tmp_ele.children
    • 模糊匹配

    • 获取文本值

      content = tmp_ele.text.strip()
    • 获取属性值

      value = tmp_ele.attrs["data-sku"]

    课后作业

    • 练习css-selector
    • 练习用beautifulsoup进行页面解析

    一个小又全的爬虫项目

    • 任务生成者
      生成爬虫任务的组件, 最大的作用就是建立生产消费者模型, 将生产者和消费者剥离, 可以达到程序暂停重启的功能.

    • 配置文件
      当前爬虫项目的基础配置信息, 目的就是统一化配置, 避免重复修改.

    • 主函数/调度器
      以逻辑控制流协同各个组件, 完成爬取工作, 具有一定的调度功能

    • 下载器
      用来和目标服务器进行交互, 获取数据的组件

    • 解析器
      用来解析非结构化的页面内容, 获取想要的数据.

    • 存储器
      用来持久化解析后的数据

      • 数据库
      • 存为本地文件, 比较推荐的格式为json, 结构严谨的可以保存为csv

    课后作业

    • 搭建第一个爬虫项目
    • 为当前爬虫项目添加代理
    • 扩展: 将当前项目改造成多线程
    • 扩展2: 将当前项目改造成多进程
    • 扩展3: 通过aiohttp, aiomysql将项目改造成协程.
  • 相关阅读:
    进程 之二
    进程
    VIM
    Linux
    编码
    Maven
    Java
    Java
    Java
    其他
  • 原文地址:https://www.cnblogs.com/final233/p/15751893.html
Copyright © 2011-2022 走看看