zoukankan      html  css  js  c++  java
  • 1. 爬虫基础

    爬虫基础

    1.简介

    爬虫:通过编写程序模拟浏览器上网,然后让其去互联网上抓取数据的过程
    

    应用分类:

    1.通用爬虫:抓取一整页面源码内容
    2.聚焦爬虫:抓取页面中局部的指定数据
    3.增量式:监测网站数据更新的情况。
    4.分布式
    

    2.requests:模拟浏览器上网

    编码流程:

    1.指定url
    2.发起请求
    3.获取响应数据
    4.持久化存储
    

    requests 基本使用

    import requests
    # 请求路径
    url = 'https://www.sogou.com/'
    # get请求返回响应对象
    response = requests.get(url=url)
    
    # 获取相应数据
    page_text = response.text #text返回的是字符串形式的相应数据
    print(page_text)
    
    # 储存数据
    with open('./sogou.html','w',encoding='utf-8') as fp:
        fp.write(page_text)
    
    

    异常访问请求

    - 异常的访问请求:
        - 非浏览器发起的请求。
        - 网站的后台是如何监测请求是否为异常请求?
            - 请求头信息:User-Agent
                - UA:请求载体的身份标识
    - 反爬机制:UA监测
    - 反反爬策略:UA伪装
    抓包工具(浏览器检查) -- Network中 -- 请求头有本机的User-Agent
    
    # 制作一个简易的网页采集器 -- 搜狗搜索
    
    import requests
    
    url = 'https://www.sogou.com/web'
    
    word = input('输入搜索关键字:')
    # 请求参数
    params = {
        'query':word
    }
    # User-Agent伪装
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'
    }
    
    response = requests.get(url=url,params=params,headers=headers)
    
    
    filename = word+'.html'
    
    with open(filename,'w',encoding='utf-8') as fp:
        fp.write(response.text)
    

    获取图片数据

    import requests
    
    # 网址
    url = 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fuserimage5.360doc.com%2F14%2F0601%2F02%2F14256129_201406010211550401.jpg&refer=http%3A%2F%2Fuserimage5.360doc.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1621499086&t=21d6a3fded64dd6af2dba9b6507e5d45'
    
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'
    }
    
    response = requests.get(url=url,headers=headers)
    
    # 获取图片的batys数据:content
    json_data = response.content
    
    # 保存
    with open('舒畅.jpg','wb') as fp:
        fp.write(json_data)
    

    3.动态加载数据

    流程:

    - 动态加载数据
        - 概念:通过对浏览器地址栏的url发起请求获取不到的数据
        - 动态加载数据的监测
            - 基于抓包工具进行局部搜索
        - 如何捕获动态加载数据?
            - 基于抓包工具进行全局搜索,定位动态加载数据对应的数据包,从数据包中可以提取
                - url
                - 请求方式
                - 请求参数
                - 请求头信息
    

    示例1:get请求

    # 豆瓣电影数据
    
    import requests
    
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36',
    }
    url = 'https://movie.douban.com/j/chart/top_list'
    
    # get请求携带的参数
    params = {
        'type': '25',
        'interval_id': '100:90',
        'action':'' ,
        'start': '0',
        'limit': '20',
    }
    
    # 获取响应的数据
    json_data = requests.get(url=url,headers=headers,params=params).json()
    print(json_data)
    
    

    示例2:post请求

    # 肯德基线下门店查询
    # http://www.kfc.com.cn/kfccda/storelist/index.aspx
    
    import requests
    
    url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
    
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'
    }
    # 获取前5页的数据
    for index in range(1,6):
        # post请求携带的参数:
        data = {
            'cname': '',
            'pid': '',
            'keyword': '北京',
            'pageIndex': index,
            'pageSize': 10,
        }
        # 获取请求数据
        response = requests.post(url=url,data=data,headers=headers)
    
        json_data = response.json()['Table1']
    
        for i in json_data:
            # 打印点名 -- 地址
            print(i['storeName'],i['addressDetail'])
    

    示例3:多次请求联合获取数据

    # 药监总局网站 http://scxk.nmpa.gov.cn:81/xk/
    
    # 查询公司详细信息:
    
    import requests
    
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'
    }
    
    list_id = []
    # 1.获取公司的id地址
    url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
    
    # post请求携带数据
    data = {
        'on': 'true',
        'page': 1,
        'pageSize': 15,
        'productName': '',
        'conditionType': 1,
        'applyname': '',
    }
    
    # 发送post请求获取响应数据
    json_data = requests.post(url,data=data,headers=headers).json()['list']
    
    for i in json_data:
        list_id.append(i['ID'])
    
    # 2.基于公司id获取获取公司的详细信息
    
    # 公司的详细信息地址
    url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
    
    for id in list_id:
        # post请求携带参数
        data = {
            'id':id
        }
        # 发送post请求获取响应数据
        json_data = requests.post(url,data,headers).json()
        print('>>>',json_data['epsName'])
    

    4.数据解析

    1.数据解析作用: 实现聚焦爬虫

    2.数据解析方式:

    1.正则
    2.bs4
    3.xpath
    4.pyquery
    

    3.原理:

    - 数据解析的通用原理
        - html是用作与数据展示。
            - 展示的数据在哪?
                - 标签的属性中
                - 标签中间
        - 原理:
            - 1.标签定位
            - 2.内容提取
    

    4.测试页面数据:

    text.html

    <html lang="en">
    <head>
    	<meta charset="UTF-8" />
    	<title>测试bs4</title>
    </head>
    <body>
    	<div>
    		<p>百里守约</p>
    	</div>
    	<div class="song">
    		<p>李清照</p>
    		<p>王安石</p>
    		<p>苏轼</p>
    		<p>柳宗元</p>
    		<a href="http://www.song.com/" title="赵匡胤" target="_self">
    			<span>this is span</span>
    		宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>
    		<a href="" class="du">总为浮云能蔽日,长安不见使人愁</a>
    		<img src="http://www.baidu.com/meinv.jpg" alt="" />
    	</div>
    	<div class="tang">
    		<ul>
    			<li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>
    			<li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>
    			<li><a href="http://www.126.com" alt="qi">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>
    			<li><a href="http://www.sina.com" class="du">杜甫</a></li>
    			<li><a href="http://www.dudu.com" class="du">杜牧</a></li>
    			<li><b>杜小月</b></li>
    			<li><i>度蜜月</i></li>
    			<li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li>
    		</ul>
    	</div>
    </body>
    </html>
    

    bs4 基本使用

    1.安装:

    pip install bs4
    

    2.使用流程

    - bs4基本使用流程:
        1.实例化一个BeautifulSoup对象,把即将被解析的页面源码数据加载到该对象中
        2.调用BeautifulSoup对象的属性和方法实现标签定位和数据提取
    

    3.BeautifulSoup对象实例化

    方式1: BeautifulSoup(fp,'lxml'):用来解析本地存储的网页文件
            
    方式2: BeautifulSoup(page_text,'lxml'):用来解析网络中请求到的数据
    

    4.解析本地存储的网页文件

    from bs4 import BeautifulSoup
    
    # 获取本地的文件句柄
    fp = open('./test.html','r',encoding='utf-8')
    
    # 实例化BeautifulSoup对象
    soup = BeautifulSoup(fp,'lxml')
    
    # 1.标签定位
    #soup.tagName(标签名称):可以将第一次出现的该标签定位到
    print(soup.div) # 获得一个对象
    
    # 2.属性定位:find(tagName,attrName(属性名称)_='attrValue')
    # 注意属性名称后有下划线
    print(soup.find('div',class_='song')) # 获得一个对象
    print(soup.findAll('div',class_='song')) # 获得对象列表
    
    # 3.选择器定位
    print(soup.select('#feng')) # 获取id='feng'的标签对象列表
    
    # 4.层级选择器:>表示一个层级,空格可以表示多个层级
    print(soup.select('.tang li > a')) # 获取class='tang'的标签里面的对象列表
    
    # 5.获取标签文本
    a_tag = soup.select('#feng')[0]
    print(a_tag.string) # string -- 取直系文本
    
    div_tag = soup.select('.song')[0]
    print(div_tag.text) # text -- 取所有文本
    
    # 6.获取标签属性
    a_tag = soup.select('#feng')[0]
    print(a_tag)
    print(a_tag['href'])
    

    5.解析网络中请求到的数据

    爬取网络小说
    import requests
    from bs4 import BeautifulSoup
    
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'
    }
    
    url = 'https://www.shicimingju.com/book/sanguoyanyi.html'
    
    # 获取响应数据
    response = requests.get(url)
    # 如果获取的数据乱码,指定编码集 utf-8 或 gbk
    response.encoding = 'utf-8'
    page_text = response.text
    # print(page_text)
    
    fp = open('三国.text','w',encoding='utf-8') # 文件对象,保存小说数据
    
    # 实例化BeautifulSoup对象
    soup = BeautifulSoup(page_text,'lxml')
    
    # 定位到小说章节标签
    tag = soup.select('.book-mulu > ul > li >a')
    # print(tag)
    # 获取小说章节名称和路径
    for i in tag:
        # 获取文章路径
        new_url = 'https://www.shicimingju.com'+i['href']
        # 获取小说章节名称
        title = i.string
        # print(new_url,title)
        # 发起get请求获取数据
        response = requests.get(new_url,headers=headers)
        response.encoding = 'utf-8' # 解决乱码
        p_text = response.text
        # print(article)
    
        # 实例化BeautifulSoup对象
        soup = BeautifulSoup(p_text, 'lxml')
    
        # 定位文章内容标签
        # article_tag = soup.select('.chapter_content')[0] # 两者都可以
        article_tag = soup.find('div',class_='chapter_content') #
    
        # 获取文章内容
        article_text = article_tag.text
    
        # 保存数据(标题和内容)
        fp.write(title+'
    '+article_text+'
    ')
        print(title,'保存成功')
    

    xpath 基本使用

    1.安装:

    pip install lxml
    

    2.使用流程

    - 编码流程 :
     1.实例化一个etree类型的对象,把即将被解析的页面源码数据加载到该对象中
     2.调用xpath方法结合着不同形式的xpath表达式进行标签定位和数据提取
    

    3.etree 对象实例化

    1. etree.parse(filePath) -- 用来解析本地存储的网页文件
    2. etee.HTML(page_text) -- 用来解析网络中请求到的数据
    

    4.解析本地存储的网页文件

    from lxml import etree
    
    # 实例化对象
    tree = etree.parse('./test.html')
    
    # 1.标签定位
    #最左侧的/:必须从根节点逐层往下定位标签
    #最左侧的//:从任意位置定位指定标签
    
    tag = tree.xpath('/html/head/title')
    tag = tree.xpath('/html//title')
    tag = tree.xpath('//title')
    
    # 2.属性定位
    tag = tree.xpath('//div[@class="tang"]')
    print(tag)
    
    # 3.索引定位:索引时从1开始
    tag = tree.xpath('//div[@class="tang"]/ul/li[3]')
    print(tag)
    
    # 4.取文本:/text()--取直系文本  //text()--取所有  
    # 获取的都是列表数据 -- 索引取值
    div_tag = tree.xpath('//div[@class="tang"]//text()')
    print(''.join(div_tag))
    
    # 5.取属性:/@attrName(属性名) -- 获取的也是列表数据
    a = tree.xpath('//a[@id="feng"]/@href')[0]
    print(a)
    
    
    

    5.解析网络中请求到的数据

    爬取图片
    # 网址: 'https://pic.netbian.com/4kmeinv/'
    import requests
    from lxml import etree
    import os
    
    # 创建储存图片的文件夹
    dirname = 'image'
    # 判断文件夹是否存在,如果不存在新建目录
    if not os.path.exists(dirname):
        os.mkdir(dirname)
    
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'
    }
    
    url = 'https://pic.netbian.com/4kmeinv/index_%d.html'
    # 爬取多张页数据
    for i in range(1,10):
        if i == 1:
            new_url = 'https://pic.netbian.com/4kmeinv/'
        else:
            new_url = format(url%i)
    
        response = requests.get(new_url,headers=headers)
        response.encoding = 'gbk' # 防止乱码
        page_text = response.text
        # print(page_text)
        # 实例化对象
        tree = etree.HTML(page_text)
    
        # 取出li标签对象列表
        li_list = tree.xpath('//*[@id="main"]/div[3]/ul/li')
        # print(li_list)
    
        # 获取图片地址和名称
        for i in li_list:
            title = i.xpath('./a/b/text()')[0] + '.jpg'
            src = 'https://pic.netbian.com' + i.xpath('./a/img/@src')[0]
            # print(title,src)
    
            # 获取图片详细数据,保存图片
            response = requests.get(src,headers=headers)
            img_data = response.content # batys流数据
            # 拼接文件路径
            filepath = dirname + '/' + title
            with open(filepath,'wb') as fp:
                fp.write(img_data)
                print(title,'保存成功')
    
    
  • 相关阅读:
    编写第一个 .NET 微服务
    Docker 基础知识编排在开发机上设置和使用 Kubernetes 环境
    将微服务部署到 Azure Kubernetes 服务 (AKS) 实践
    .NET Task.Run vs Task.Factory.StartNew
    Python上下文管理器
    Python可迭代的对象与迭代器的对比
    开发你的第一个SpringBoot应用
    Flask的Blueprints和Views
    Flask项目发布流程
    长篇大论Python生成器
  • 原文地址:https://www.cnblogs.com/jia-shu/p/14682858.html
Copyright © 2011-2022 走看看