zoukankan      html  css  js  c++  java
  • 爬虫 --- 02. 爬取图片,数据解析

    一.两种爬取图片的方法

      ①requests方法

    import requests
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
    }
    
    img_url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1559019106959&di=3aa954df95d2e55083d85de8391118c5&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201601%2F28%2F20160128195606_xvawC.jpeg'
    
    img_data = requests.get(url=img_url,headers=headers).content
    
    with open('./meinv.jpg','wb') as fp:
        fp.write(img_data)

      ②request方法

    from urllib import request
    img_url
    = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1559019106959&di=3aa954df95d2e55083d85de8391118c5&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201601%2F28%2F20160128195606_xvawC.jpeg'
    request.urlretrieve(img_url,
    './meishaonv.jpg') #图片,压缩包,视频等一定要加好后缀

    二.数据解析

      1.正则

      单字符:
            . : 除换行以外所有字符
            [] :[aoe] [a-w] 匹配集合中任意一个字符
            d :数字  [0-9]
            D : 非数字
            w :数字、字母、下划线、中文
            W : 非w
            s :所有的空白字符包,括空格、制表符、换页符等等。等价于 [ f
    
    	v]。
            S : 非空白
        数量修饰:
            * : 任意多次  >=0
            + : 至少1次   >=1
            ? : 可有可无  0次或者1次
            {m} :固定m次 hello{3,}
            {m,} :至少m次
            {m,n} :m-n次
        边界:
            $ : 以某某结尾 
            ^ : 以某某开头
        分组:
            (ab)  
        贪婪模式: .*
        非贪婪(惰性)模式: .*?
    
        re.I : 忽略大小写
        re.M :多行匹配
        re.S :单行匹配
    
        re.sub(正则表达式, 替换内容, 字符串)
    正则解析
      需求:爬取糗事百科中所有的糗图图片数据
      实现:
        检查页面中的图片数据是否为动态加载的
        将当前页面的源码数据请求到
        使用正则表达式定位相关的img标签,然后获取img的src属性值
        对src的属性值发起请求获取图片数据
        持久化存储图片数据
    import requests
    import re
    import os
    from urllib import request
    if not os.path.exists('./qiutu'): os.mkdir('./qiutu')
    headers
    = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' } url = 'https://www.qiushibaike.com/pic/'

    page_text = requests.get(url=url,headers=headers).text ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>' img_url = re.findall(ex,page_text,re.S) for url in img_url: url = 'https:'+url img_name = url.split('/')[-1] img_path = './qiutu/'+img_name request.urlretrieve(url,img_path) print(img_name,'下载成功!!!')

      2. bs4解析

      ①环境安装

    输入

      pip3 install bs4   pip3 install lxml

       ②原理

    解析原理:
      实例化一个Beautifulsoup的对象,且将页面源码数据加载到该对象中
      使用该对象的相关属性和方法实现标签定位和数据提取
    实例化Beautifulsoup对象
      BeautifulSoup(page_text,'lxml'):将从互联网上请求到的页面源码数据加载到该对象中
      BeautifulSoup(fp,'lxml'):将本地存储的一样页面源码数据加载到该对象中

    soup = BeautifulSoup(fp,'lxml')   #示例化

       ③定位

    #①soup.tagName:只可以定位到第一次出现的tagName标签
      soup.title
      soup.div
    #soup.find(‘tagName’)
    soup.find('a')  # soup.a
    #②属性定位
    soup.find('div',class_='song')
    #③find_all
    soup.find_all('div')[2]
    #④select('选择器')
    soup.select('.song')

      ‘>’:表示一个层级

      soup.select('.tang > ul > li > a')

      空格:表示多个层级

      soup.select('.tang a')

       ④取值

    #取文本:string取的是直系的文本数据,text获取的是全部的数据
    soup.p.string

     #取后代中的所有文本数据

     soup.find('div',class_='tang').get_text()
      soup.find('div',class_='tang').text

     
    #取属性
    soup.a['href']

       ⑤示例

    爬取古诗文网的三国演义小说(过程):
      页面数据是否为动态加载   在首页中解析章节标题和标题对应的详情页的url   对详情页url发起请求获取详情页的源码数据   检查详情页是否存在动态加载的数据   解析详情页中的章节内容   持久化存储
    import requests
    from bs4 import BeautifulSoup

    url = 'http://www.shicimingju.com/book/sanguoyanyi.html' page_text = requests.get(url=url,headers=headers).text #数据解析:标题和url soup = BeautifulSoup(page_text,'lxml') li_list = soup.select('.book-mulu > ul > li') fp = open('./sanguo.txt','w',encoding='utf-8') for li in li_list: title = li.a.string detail_url = 'http://www.shicimingju.com'+li.a['href'] # print(title,detail_url) #单独对详情页发起请求获取源码数据 detail_page_text = requests.get(url=detail_url,headers=headers).text soup = BeautifulSoup(detail_page_text,'lxml') content = soup.find('div',class_="chapter_content").text fp.write(title+' '+content+' ') print(title,':下载成功!') fp.close()

       3. xpath解析

      ①环境安装

    pip install lxml

    - 解析效率比较高
    - 通用性最强的

      ②工作原理

    - 解析原理:
        - 实例化一个etree对象且将即将被解析的页面源码数据加载到该对象中
        - 使用etree对象中的xpath方法结合着xpath表达式进行标签定位和数据提取
    - 实例化etree对象
        - etree.parse('本地文件路径')
        - etree.HTML(page_text)

    from lxml import etree
    tree = etree.parse('./test.html')    #实例化对象

       ③定位

    #①定位title标签
    tree.xpath('/html/head/title')
    tree.xpath('/html//title')
    tree.xpath('//title')    #推荐
    #②定位class=song的div
    tree.xpath('//div[@class="song"]')
    tree.xpath('//div[2]')  #xpath表达式中的索引是从1开始

     tree.xpath('//div[@class="tang"]/ul/li[4]/a')
      tree.xpath('//div[@class="tang"]//li[4]/a')

       ④取值

    #取文本(获取李清照) /text()  //text()
    tree.xpath('//div[@class="song"]/p[1]/text()')[0]
    tree.xpath('//div[@class="song"]/text()')
    #取属性
    tree.xpath('//a/@title')

      ⑤示例1

    #爬取boss直聘爬虫岗位的信息
    from lxml import etree
    
    
    import requests
    
    url = 'https://www.zhipin.com/job_detail/?query=python%E7%88%AC%E8%99%AB&city=101010100&industry=&position='
    page_text = requests.get(url=url,headers=headers).text
    
    #数据解析(jobTitle,salary,company)
    tree = etree.HTML(page_text)
    li_list = tree.xpath('//div[@class="job-list"]/ul/li')
    for li in li_list:
        title = li.xpath('.//div[@class="job-title"]/text()')[0]
        salary = li.xpath('.//span[@class="red"]/text()')[0]
        company = li.xpath('.//div[@class="company-text"]/h3/a/text()')[0]
        print(title,salary,company)

      ⑥示例2(管道符的使用)

    #爬取全国城市名称
    import requests
    from lxml import etree
    
    url = 'https://www.aqistudy.cn/historydata/'
    page_text = requests.get(url=url,headers=headers).text
    
    tree = etree.HTML(page_text)
    # hot_city = tree.xpath('//div[@class="bottom"]/ul/li/a/text()')
    # all_city = tree.xpath('//div[@class="bottom"]/ul/div[2]/li/a/text()')
    # all_city
    
    tree.xpath('//div[@class="bottom"]/ul/div[2]/li/a/text() | //div[@class="bottom"]/ul/li/a/text()')

      ⑦示例3(解决中文乱码问题)

    #爬取4k图片带标题

    import requests
    from lxml import etree start_page = int(input('start page num:')) end_page = int(input('end page num:')) if not os.path.exists('./meinvs'): os.mkdir('./meinvs') #通用的url模板(不能修改) url = 'http://pic.netbian.com/4kmeinv/index_%d.html' for page in range(start_page,end_page+1): if page == 1:                   new_url = 'http://pic.netbian.com/4kmeinv/' else:          #除第一页外,其他url一致 new_url = format(url%page) response = requests.get(url=new_url,headers=headers) # response.encoding = 'utf-8'    #第一种 page_text = response.text #解析名称和图片的src属性值 tree = etree.HTML(page_text) li_list = tree.xpath('//div[@class="slist"]/ul/li') for li in li_list: img_name = li.xpath('./a/img/@alt')[0] img_name = img_name.encode('iso-8859-1').decode('gbk')+'.jpg'  #第二种   img_src = 'http://pic.netbian.com'+li.xpath('./a/img/@src')[0] img_path = './meinvs/'+img_name request.urlretrieve(img_src,img_path) print(img_name,'下载成功!!!')
  • 相关阅读:
    前端面试题
    js collection
    javascript变量声明提升(hoisting)
    css3动画
    神奇的meta
    wap站bug小结
    前端collection
    js拾遗
    prototype之初印象
    自定义scrollBottom的值
  • 原文地址:https://www.cnblogs.com/sc-1067178406/p/10939905.html
Copyright © 2011-2022 走看看