zoukankan      html  css  js  c++  java
  • python爬取网站之preparation

    python爬取网站之preparation

      一:爬取流程

    1.准备工作:

      通过浏览器查看目标网页

    2.获取数据:

      通过HTTP库向目标网站发送请求,请求可以包含header等信息,如果网站能正常响应,会得到一个REsponse,这就是网页的内容

    3.解析内容:

      得到的内容有可能是html,还有可能是xml,可以用页面解析库或者正则表达式进行解析

    4.保存数据:

      可以保存为txt文本,也可以保存为数据库,也可以保存为你想要保存的形式

     

    二:准备工作:

    1. 允许代码出现中文#-*-coding:utf-8-*-(可以保证在代码中可以出现中文)

    2. 可以加入main函数用于测试程序

      if_name=="_main_":#规范
      ​
      eg:
          if __name__=="__main__":#当程序执行的时候
          #调用main函数
              def main():
                  print("hello")
    3. 引入库:import

      #引入系统模块:
      import os
      import sys
      ​
      #引入第三方模块:需要外部引入
      import re       #正则表达式进行文字匹配
      import urllib   #制定url,获取网页数据
      import xlwt     #进行excel操作
      import bs4      #网页解析,获取数据
      from bs4 import BeautifulSoup   #网页解析,获取数据
      import sqlLite3 #进行SQLite数据库操作
      #如何操作,进行外部引入:
      terminal->打开控制台->pip ps4/re/urllib/xlwt#临时安装
      File->setting->project+名字->project interpreter->右上角+号->搜索框搜索引入的包,并添加
    4. 请求数据:post和get请求:

      import urllib.request 
      import urllib.parse     #模拟浏览器,封装数据所用的包  
      #请求网页,获取一个get对象                                                                   
      response=urllib.request.urlopen("http://www.baidu.com")#open一个网页                  
      print(response.read().decode('utf-8'))#输出读取对象的信息,而不是直接输出对象名,注意为了王编码更加流畅,使用utf-8解码 
      #post请求,一般用在模拟用户网站登录的时候,必须给一个封装后的表单,否则直接post是不允许的         
      #这里将数据使用二进制转换,并以utf-8的格式封装到data,并使用parse包封装成浏览器发送请求                  
      data=bytes(urllib.parse.urlencode({"password":"132456"}),encoding="ut
      #使用post请求的时候,必须在最后写明post,并且把封装好的表单写上                                 
      response=urllib.request.urlopen("http://httpbin.org/post",data=data) 
                 
      #get请求,同上只需要换成get就好了
    5. 超时现象(也就是网站发现了是爬虫,拒绝访问)

      #使用try块,捕获异常,并在获取request对象的时候,加上timeout属性(检测执行时间)
      try:
          response=urllib.request.urlopen("http://www.baidu.com",timeout=2)
          print(response.read().decode('utf-8'))
      except URLError as E:
          print("URLError")
    6. 获取header响应头

      response.getheaders()#获取所有header的表单
      response.getheader("Server").decode('utf-8')#获取指定的header的值,以utf-8解码
    7. 当遇到418的时候,User-Agent需要改变一下

      #url:请求地址,data:封装程浏览器发送的表单,headers:返回的响应头,method:响应
      url="http://baidu.com"
      headers={
          User-Agent:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Edg/85.0.564.63"
      }
      data=bytes(urllib.parse.urlencode({"password":"132456"}),encoding="utf-8")
      ​
      req=urllib.request.Request(url=url,data=data,headers=headers,method ="POST")
      response=urllib.request.urlopen(req)#注意:这里不是传地址,而是直接传了一个req对象,里面包含了所需要的的素有信息
      print(response.read().decode("utf-8")
      #User-Agent所在位置:F12->NetWork->Header->Request Header->User-Agent后面所有的内容

       

    三:获取数据:(可以使用for循环,循环调用实现翻页效果)

    def askURL(url):
        #User-Agent必须与其完全一致才行
        head={#模拟浏览器头部信息,向服务器发送消息
            User-Agent:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Edg/85.0.564.63"
        }
        #这个请求标头request是为了给response服务以及传参的
        request =urllib.request.Request(url,headers=head)
        html=""
        try:
            response=urllib.request.urlopen(request)
            html=response.read().decode("utf-8")#以html的方式读取数据
            print(html)
        except urllib.error.URLError as e:
            if hasatter(e,"code"):#错误1
                print(e.code)
            if hasatter(e,"reason"):#错误2
                print(e.reason)

     

      重点:BeautifulSoup使用方法:

    file=open("./baidu.html","rb")
    html=file.read()
    #这里是核心,将筛选器bs对象创建出来,可以是html对象,也可以是xml对象,自动补全标签
    bs=BeautifulSoup(html."html.paser")#第一个参数是将转换的类型,第二个参数是固定格式(文件.paser)
    1.获取Tag标签及其内容:
    print(bs.title)
    print(bs.a)
    print(bs.head)
    ​
    2.NavigableString,获取标签里面的内容(字符串)
    print(bs.title.tring)
    print(bs.a.string)
    ​
    3.BeautifulSoup:获取标签整个文档内容
    print(bs)
    ​
    4.attr:获取标签下所存在的元素成员,并且以表单的形式返回
    print(bs.a.attrs)
    #输出:{‘class':['manbv'],'href':'ahsfiasf'}
    5.Comment:是一个特殊的NavigableString,但是输出的时候不包含注释符号
    print(bs.a.string)
    ​
    6.contents:遍历文件树
    #tag的.content属性可以将tag的子节点以列表的方式输出
    print(bs.head.contents)
    #用列表索引来获取他的某一个元素
    print(bs.head.contents[1])
    ​
    7.遍历文档树:
        soup = BeautifulSoup(html_doc,'lxml')
        #     1、直接使用
        print(soup.html)
        print(type(soup.html)) #类型变成了element_tag
        print(soup.a)
        #     2、获取标签的名称
        print(soup.a.name)
        #     3、获取标签的属性
        print(soup.a.attrs)
        #     4、获取标签的内容
        print(soup.p.text)
        #     5、嵌套选择
        print(soup.html.body.p)
        #     6、子节点、子孙节点
        print(soup.p.children)
        #     7、父节点、祖先节点
        print(soup.b.parent)
        print(soup.b.parents)
        
    8.搜索文档树:
    格式:
        标签查找与属性查找:
        find与findall
        find找一个
        findall找所有
        标签:
            - 字符串过滤器   字符串全局匹配
                name 属性匹配
                attrs 属性查找匹配
                text 文本匹配
        
            - 正则过滤器
                re模块匹配
        
            - 列表过滤器
                列表内的数据匹配
        
            - bool过滤器
                True匹配
        
            - 方法过滤器
                用于一些要的属性以及不需要的属性查找。
            
        属性:
            - class_
            - id
            
    # 第一个参数是解析文本
    # 第二个参数是解析器
    soup = BeautifulSoup(html_doc, 'lxml')
    # 1、字符串
    # find的默认参数 第一个是name、第二个是attrs、第四个是text
    # name: 根据标签名匹配节点
    print(soup.find('p'))  # 获取第一个p标签
    print(soup.find_all(name='p'))  # 获取所有的p标签
    # attrs: 根据属性查找匹配节点
    print(soup.find(attrs={'id': 'p'}))  # 查找id为p的标签
    print(soup.find_all(attrs={'class': 'sister'}))  # 查找class为sister的所有标签
    # text: 根据文本匹配文档树内的文本
    # 推荐配合其他匹配规则使用,否则毫无意义
    print(soup.find(text='$37'))  # 查找标签内为$37的文本
    # name与text配合使用
    print(soup.find_all(name='p', text='$37'))  # 查找所有文本为$37的p标签
    # name与attrs配合使用
    print(soup.find(name='a', attrs={'id': 'link2'}))  # 查找第一个id为link2的a标签
    # attrs与text配合使用
    print(soup.find_all(attrs={'id': 'link2'}, text='Lacie'))  # 查找所有id为link2,文本为Lacie的标签
    # name、attrs、text组合使用
    print(soup.find_all(name='a', attrs={'id': 'link3'}, text='Tillie'))  # 查找所有id为link3,文本为Tillie的a标签
    ​
    ​
    # 2、正则
    print(soup.find(name=re.compile('a')))  # 通过第一个标签名带有a的节点
    print(soup.find_all(attrs={'id': re.compile('link')}))  # 匹配所有id名带有link的节点
    print(soup.find_all(text=re.compile('and')))  # 匹配所有文本带有"and"的节点
    ​
    ​
    # 3、列表 (列表内可以匹配多个)
    print(soup.find_all(name=['a', re.compile('e')]))  # 匹配所有a标签节点与所有标签中带有e的节点
    print(soup.find_all(text=['$']))  # 找不到,因为$是精确查找
    print(soup.find_all(text=['$37']))  # 查找$37文本,这样查找是没有意义的
    print(soup.find_all(text=[re.compile('$')]))  # 正则中$是特殊字符,所以需要转义
    ​
    ​
    # 4、bool
    print(soup.find_all(name=True))  # 查找所有有标签名的节点
    print(soup.find_all(attrs={'id': True}))  # 查找所有有id的节点
    print(soup.find_all(text=True))  # 查找所有文本
    ​
    ​
    # 5、方法
    # 写一个只要有class没有id的a标签的函数
    def has_class_not_id(arg):
        if arg.name == 'a' and arg.has_attr('class') and not arg.has_attr('id'):
            return arg.name
    ​
    print(soup.find_all(name=has_class_not_id))  # 通过has_class_not_id的函数匹配节点
    ​
    ​
    # 6、标签与属性查找
    # 标签
    print(soup.find_all(attrs={'class': 'sister'}))
    ​
    # 属性
    # 根据class属性查找,因为class是关键字,所以后面需要加下划线
    print(soup.find_all(class_='sister'))
    # 根据id属性查找
    print(soup.find_all(id='link2'))

     

  • 相关阅读:
    Python学习笔记(十一)
    Python学习笔记(十)
    Python学习笔记(九)
    Fatal error in launcher:Unable to create process using '"'
    通过xrdp服务实现windows远程桌面连接树莓派
    Python学习笔记(七)
    Python 杂集
    Python入门小练习
    Python标准库
    [Chrome](CSS) 解决Chrome font-size 小于 12px 无效
  • 原文地址:https://www.cnblogs.com/instead-everyone/p/13764908.html
Copyright © 2011-2022 走看看