zoukankan      html  css  js  c++  java
  • 爬虫基础以及 re,BeatifulSoup,requests模块使用

    爬虫基础以及BeatifulSoup模块使用

      爬虫的定义:向网站发起请求,获取资源后分析并提取有用数据的程序 
    

    爬虫的流程

    • 发送请求 ---> request
    • 获取响应内容 ---> response
    • 解析内容 ---> BeatifulSoup
    • 保存数据 ---> mysql
    #1、发起请求
    使用http库向目标站点发起请求,即发送一个Request
    Request包含:请求头、请求体等
    
    #2、获取响应内容
    如果服务器能正常响应,则会得到一个Response
    Response包含:html,json,图片,视频等
    
    #3、解析内容
    解析html数据:正则表达式,第三方解析库如Beautifulsoup,pyquery等
    解析json数据:json模块
    解析二进制数据:以b的方式写入文件
    
    #4、保存数据
    数据库
    文件
    

    1.Request请求内容

    1.1请求方式:

        常用的请求方式:GET,POST
        其他请求方式:HEAD,PUT,DELETE,OPTHONS
    
        ps:用浏览器演示get与post的区别,(用登录演示post)
    
        post与get请求最终都会拼接成这种形式:k1=xxx&k2=yyy&k3=zzz
        post请求的参数放在请求体内:
            可用浏览器查看,存放于form data内
        get请求的参数直接放在url后
    

    1.2请求url

        url全称统一资源定位符,如一个网页文档,一张图片
        一个视频等都可以用url唯一来确定
    
        url编码
        https://www.baidu.com/s?wd=图片
        图片会被编码(看示例代码)
    
    
        网页的加载过程是:
        加载一个网页,通常都是先加载document文档,
        在解析document文档的时候,遇到链接,则针对超链接发起下载图片的请求
    

    1.3请求头

    User-agent:告诉它这是浏览器发过来的请求(请求头中如果没有user-agent客户端配置,服务端可能将你当做一个非法用户)务必加上
    host:
    cookies:cookie用来保存登录信息
    Referer:上一次的跳转路径
    

    1.4请求体

        如果是get方式,请求体没有内容
        如果是post方式,请求体是format data
    
        1、登录窗口,文件上传等,信息都会被附加到请求体内
        2、登录,输入错误的用户名密码,然后提交,就可以看到post,正确登录后页面通常会跳转,无法捕捉到post
    

    2.响应Response内容

    2.1响应状态

        200:代表成功
        301:代表跳转
        404:文件不存在
        403:权限
        502:服务器错误
    

    2.2Respone header

        Location:跳转
        set-cookie:可能有多个,是来告诉浏览器,把cookie保存下来
    

    2.3preview就是网页源代码.

        最主要的部分,包含了请求资源的内容
        如网页html,图片
        二进制数据等
    

    BeatifulSoup模块和requests模块

        requests可以模拟浏览器的请求,BeatifulSoup是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式;
    

    安装 BeautifulSoup

    1.安装beautifulsoup4

    pip install beautifulsoup4
    

    2.安装解析器

    • lxml HTML 解析器:速度快,容错能力强 *****

        Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,其中一个是 lxml
      
    pip install lxml
    
    • html5lib 依照浏览器方式解析文档

        另一个可供选择的解析器是纯Python实现的 html5lib , html5lib的解析方式与浏览器相同,可以选择下列方法来安装html5lib:
      
    pip install html5lib
    

    使用

    1.引用BeautifulSoup模块

    from bs4 import BeautifulSoup
    

    常用参数

    requests模块:

    • requests.get 请求内容
    • response.encoding 解码方式
    • response.text 页面内容

    BeautifulSoup4模块:

    • BeautifulSoup(response.text, "lxml") #处理容错格式: BeautifulSoup(页面内容, "lxml")

    固定格式部分--获取页面内容

    import requests
    from bs4 import BeautifulSoup
    
    # 请求内容
    response = requests.get(
        # 指定 url 地址
        url='https://www.autohome.com.cn/news/',
        # URL 头部信息
        headers={
            # 伪装头部信息
            "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
            # 伪装从哪个页面来源
            "Referer": "https://www.autohome.com.cn/",
            # 主机地址
            "Host": "www.autohome.com.cn",
        }
    )
    # 解码方式
    response.encoding = 'utf-8'
    
    # 将HTML文本转换为一个对象
    soup = BeautifulSoup(response.text, "lxml")
    
    # 处理好缩进,结构化显示(易于查看)
    # res = soup.prettify()                         
    

    1.获取标签

    1.获取标签(p标签,a标签)

    print(soup.p)      # 存在多个相同的标签则只返回第一个
    print(soup.a)      # 存在多个相同的标签则只返回第一个
    

    2.获取标签的名称(p)

    print(soup.p.name)
    

    3.获取标签的属性

    print(soup.div.attrs)
    

    输出:

    {'id': 'auto-header', 'class': ['topbar']}
    

    4.获取标签的内容

    print(soup.span.string)              # span下的文本只有一个时,取到,否则为None
    print(soup.span.strings)             # 拿到一个生成器对象, 取到span下所有的文本内容
    print(soup.span.text)                # 取到span下所有的文本内容
    

    5.嵌套选择(取出 body 下的 a标签 第一个;)

    print(soup.head.title.text)
    print(soup.body.a.string)
    

    6.子节点、子孙节点

    print(soup.p.contents)            # p下所有子节点
    print(soup.p.children)            # 得到一个迭代器,包含p下所有子节点
    
    - 循环该节点,得到索引和值
    for i,child in enumerate(soup.p.children):
        print(i,child)
    

    7.父节点

    print(soup.a.parent) #获取a标签的父节点
    

    8.兄弟节点

    print(soup.a.next_sibling)           # 下一个兄弟
    print(soup.a.previous_sibling)       # 上一个兄弟
    print(soup.a.next_siblings)          # 下面所有兄弟们=>生成器对象
    print(soup.a.previous_siblings)      # 上面所有兄弟们=>生成器对象
    

    2.过滤器

        将拿到的数据按照一定规则进行过滤,提取有用的信息;
    

    2.1使用BeautifulSoup的find和find_all

    • 查询find_all 列表时,需要指定标签后,才可继续使用find方法

    2.2按照类class 进行查找

    class的两种用法

    # attrs={"class": "sister"}
    # class_="sister"
    # 两种查出class 类的方法
    print(soup.find_all(name="div", attrs={"class": "sister"}))
    print(soup.find_all(name="div", class_="sister"))              # 这两个是一样的
    
    # 两种查出 id 的方法
    print(soup.find_all(attrs={"id":"link3"}))                     # 这两个是一样的,只是表示方式不一样
    print(soup.find_all(id="link3"))
    

    1.找到文档中所有 ul标签 class 为 article 的标签

    print(soup.find_all(name="ul", attrs={"class": "article"}))     # 找到标签名是ul,属性名是article,
    或
    print(soup.find_all('ul', class_='article'))     
                   
    

    2.找到文档中div标签,属性为advlist fn-clear标签,顺序错误也匹配不成功

    print(soup.find_all(name="div", class_="advlist fn-clear"))
    

    3.查找依照advl 开头的类

    print(soup.find_all(name="div", class_=re.compile("^advl")))
    

    2.3使用正则 re 模块进行匹配

    1.找到b开头的的标签

    import re
    print(soup.find_all(name=re.compile("^b")))    
    

    2.找到id包含link的标签

    print(soup.find_all(attrs={"id":re.compile("link")})) 
    

    3.找带有$价钱的文本

    print(soup.find_all(text=re.compile(r"$")))                 # 找带有$价钱的文本
    

    4.找到文本中包含 Money字符串 或 $符 的字符串

    print(soup.find_all(text=["Money", re.compile(r"$")]))      # 找text 中有Money或 $符 的文本
    

    5.获取 digg-logo 字符串

    a = '<a class="digg-logo" href="/"></a>'
    digg = re.findall('class="(.*)" href=', str(a))[0]
    
    print(digg)
    

    输出:

    digg-logo
    

    2.4列表中任一元素匹配的内容返回

    1.找a标签或者b开头的所有的标签

    print(soup.find_all(name=["a", re.compile("^b")]))          
    

    2.5True:可以匹配任何值

    1.找到所有标签的标签名属性的标签(所有)

    print(soup.find_all(name=True))                              # 找到所有标签的标签名(所有)
    

    2.找到只要有id属性的标签

    print(soup.find_all(attrs={"id":True}))                      # 找到只要有id属性的
    

    3.找到p标签,并且具有id 属性的

    print(soup.find_all(name="p",attrs={"id":True})) 
    

    2.6自定义过滤器;

    1.只接受一个元素参数 ,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False

    def has_class_not_id(tag):
        # return tag.has_attr('class') and not tag.has_attr('id')                      # 找到包含class 标签,但是不包含id属性的标签(子标签中含id属性,会被忽略)
        # return tag.has_attr('id') and not tag.has_attr('class')                      # 只包含 id 不包含 class 属性
        return tag.name == "a" and tag.has_attr("class") and not tag.has_attr("id")    # a 标签,包含class 属性,不包含id属性
        
    print(soup.find_all(has_class_not_id)) 
    

    2.指定标签,是否深入查询recursive=False or True

    • recursive = True # 从子子孙孙所有内部找到
    • recursive = False # 如果只想搜索当前tag的直接子节点(就不往里面找了),可以使用参数 recursive=False
    print(soup.body.div.find_all(attrs={"class": "minitop"}, recursive=False))        # 只查询body标签里子节点包含 "class" = "sister" 的标签
    

    3.CSS选择器:select

    1.class为 ad-top-1111 下的 div 标签

    print(soup.select('.ad-top-1111 div'))
    

    2.查找id等于 auto-header-channel19 的标签

    print(soup.select('#auto-header-channel19'))
    

    3.获取class为 ad-top-1111 下的 div 标签 获取它的属性

    print(soup.select('.ad-top-1111 div')[0].attrs)
    

    4.获取class为 ad-top-1111 下的 div 标签,下的内容

    print(soup.select('.ad-top-1111 div')[0].get_text)
    

    获取a标签内部属性:

    1.获取img标签中的url

    img_url = "https:" + img.get("src")
    

    2.获取a标签中的url

    a_url = img_url = "https:" + a.get('href')
    
  • 相关阅读:
    C#分割字符串
    Android中this、super的区别
    Android activity跳转方式
    Android中的各种单位
    Android布局方式_RelativeLayout
    Parallelism , Partitioner
    编译hadoop,spark遇到的问题总结
    scala,spark练习题提高
    元组复杂例子
    sparksql 操作hive
  • 原文地址:https://www.cnblogs.com/baolin2200/p/8376749.html
Copyright © 2011-2022 走看看