zoukankan      html  css  js  c++  java
  • 【网络爬虫学习】实战,爬取网页以及贴吧数据

    实战一

    抓取您想要的网页,并将其保存至本地计算机。

    首先我们对要编写的爬虫程序进行简单地分析,该程序可分为以下三个部分:

    • 拼接 url 地址
    • 发送请求
    • 将照片保存至本地

    明确逻辑后,我们就可以正式编写爬虫程序了。

    导入所需模块

    from urllib import request, parse
    

    拼接 URL 地址

    定义 URL 变量,拼接 url 地址。代码如下所示:

    url = 'http://www.baidu.com/s?wd={}'
    
    word = input('请输入想要搜索的内容:')
    params = parse.quote(word)
    full_url = url.format(params)
    

    向URL发送请求

    发送请求主要分为以下几个步骤:

    • 创建请求对象-Request
    • 获取响应对象-urlopen
    • 获取响应内容-read

    代码如下所示:

    # 重构请求头
    headers = {
        'User-Agent':
        'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'
    }
    # 创建请求对应
    req = request.Request(url=full_url, headers=headers)
    # 获取响应对象
    res = request.urlopen(req)
    # 获取响应内容
    html = res.read().decode('utf-8')
    

    保存为本地文件

    把爬取的照片保存至本地,此处需要使用 Python 编程的文件 IO 操作,代码如下:

    filename = word + '.html'
    with open(filename, 'w', encoding='utf-8') as f:
        f.write(html)
    

    完整程序如下所示:

    from urllib import request, parse
    # 1.拼url地址
    url = 'http://www.baidu.com/s?wd={}'
    
    word = input('请输入想要搜索的内容:')
    params = parse.quote(word)
    full_url = url.format(params)
    # 2.发请求保存到本地
    # 重构请求头
    headers = {
        'User-Agent':
        'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'
    }
    # 创建请求对应
    req = request.Request(url=full_url, headers=headers)
    # 获取响应对象
    res = request.urlopen(req)
    # 获取响应内容
    html = res.read().decode('utf-8')
    # 3.保存文件至当前目录
    filename = word + '.html'
    with open(filename, 'w', encoding='utf-8') as f:
        f.write(html)
    
    

    尝试运行程序,并输入 RioTianの博客园,确认搜索,然后您会在当前的工作目录中找到“RioTianの博客园.html”文件。

    函数式编程修改程序

    Python 函数式编程可以让程序的思路更加清晰、易懂。接下来,使用函数编程的思想更改上面代码。

    定义相应的函数,通过调用函数来执行爬虫程序。修改后的代码如下所示:

    from urllib import request, parse
    
    
    # 拼接URL地址
    def get_url(word):
        url = 'http://www.baidu.com/s?{}'
        # 此处使用urlencode()进行编码
        params = parse.urlencode({'wd': word})
        url = url.format(params)
        return url
    
    
    # 发请求,保存本地文件
    def request_url(url, filename):
        headers = {
            'User-Agent':
            'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'
        }
        # 请求对象 + 响应对象 + 提取内容
        req = request.Request(url=url, headers=headers)
        res = request.urlopen(req)
        html = res.read().decode('utf-8')
        # 保存文件至本地
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(html)
    
    
    # 主程序入口
    if __name__ == '__main__':
        word = input('请输入搜索内容:')
        url = get_url(word)
        filename = word + '.html'
        request_url(url, filename)
    

    除了使用函数式编程外,也可以使用面向对象的编程方法(实战二),在后续内容中会做相应介绍。

    实战二

    抓取百度贴吧(https://tieba.baidu.com/)页面,比如 Python爬虫吧、编程吧,只抓取贴吧的前 5 个页面即可。

    判断页面类型

    通过简单的分析可以得知,待抓取的百度贴吧页面属于静态网页,分析方法非常简单:打开百度贴吧,搜索“Python爬虫”,在出现的页面中复制任意一段信息,比如“爬虫需要 http 代理的原因”,然后点击右键选择查看源码,并使用 Ctrl+F 快捷键在源码页面搜索刚刚复制的数据,如下所示:

    静态网页判断

    由上图可知,页面内的所有信息都包含在源码页中,数据并不需要从数据库另行加载,因此该页面属于静态页面。

    寻找URL变化规律

    接下来寻找要爬取页面的 URL 规律,搜索“Python爬虫”后,此时贴吧第一页的的 url 如下所示:

    https://tieba.baidu.com/f?ie=utf-8&kw=python爬虫&fr=search
    

    点击第二页,其 url 信息如下:

    https://tieba.baidu.com/f?kw=python爬虫&ie=utf-8&pn=50
    

    点击第三页,url 信息如下:

    https://tieba.baidu.com/f?kw=python爬虫&ie=utf-8&pn=100
    

    重新点击第一页,url 信息如下:

    https://tieba.baidu.com/f?kw=python爬虫&ie=utf-8&pn=0
    

    如果还不确定,您可以继续多浏览几页。最后您发现 url 具有两个查询参数,分别是 kw 和 pn,并且 pn 参数具有规律性,如下所示:

    第n页:pn=(n-1)*50
    
    #参数params
    pn=(page-1)*50
    params={
             'kw':name,
             'pn':str(pn)
            }
    

    url 地址可以简写为:

    https://tieba.baidu.com/f?kw=python爬虫&pn=450
    

    编写爬虫程序

    下面以类的形式编写爬虫程序,并在类下编写不同的功能函数,代码如下所示:

    from urllib import request,parse
    import time
    import random
    from ua_info import ua_list #使用自定义的ua池
    
    #定义一个爬虫类
    class TiebaSpider(object):
        #初始化url属性
        def __init__(self):
            self.url='http://tieba.baidu.com/f?{}'
    
        # 1.请求函数,得到页面,传统三步
        def get_html(self,url):
            req=request.Request(url=url,headers={'User-Agent':random.choice(ua_list)})
            res=request.urlopen(req)
            #windows会存在乱码问题,需要使用 gbk解码,并使用ignore忽略不能处理的字节
            #linux不会存在上述问题,可以直接使用decode('utf-8')解码
            html=res.read().decode("gbk","ignore")
            return html
        # 2.解析函数,此处代码暂时省略,还没介绍解析模块
        def parse_html(self):
            pass
        # 3.保存文件函数
        def save_html(self,filename,html):
            with open(filename,'w') as f:
                f.write(html)
        # 4.入口函数
        def run(self):
            name=input('输入贴吧名:')
            begin=int(input('输入起始页:'))
            stop=int(input('输入终止页:'))
            # +1 操作保证能够取到整数
            for page in range(begin,stop+1):
                pn=(page-1)*50
                params={
                    'kw':name,
                    'pn':str(pn)
                }
                #拼接URL地址   
                params=parse.urlencode(params)
                url=self.url.format(params)
                #发请求
                html=self.get_html(url)
                #定义路径
                filename='{}-{}页.html'.format(name,page)
                self.save_html(filename,html)
                #提示
                print('第%d页抓取成功'%page)
                #每爬取一个页面随机休眠1-2秒钟的时间
                time.sleep(random.randint(1,2))
    #以脚本的形式启动爬虫
    if __name__=='__main__': 
        start=time.time()
        spider=TiebaSpider() #实例化一个对象spider
        spider.run() #调用入口函数
        end=time.time()
        #查看程序执行时间
        print('执行时间:%.2f'%(end-start))  #爬虫执行时间
    

    程序执行后,爬取的文件将会保存至 Pycharm 当前工作目录,输出结果:

    输入贴吧名:python爬虫
    输入起始页:1
    输入终止页:2
    第1页抓取成功
    第2页抓取成功
    执行时间:12.25
    

    以面向对象方法编写爬虫程序时,思路简单、逻辑清楚,非常容易理解,上述代码主要包含了四个功能函数,它们分别负责了不同的功能,总结如下:

    1) 请求函数

    请求函数最终的结果是返回一个 HTML 对象,以方便后续的函数调用它。

    2) 解析函数

    解析函数用来解析 HTML 页面,常用的解析模块有正则解析模块、bs4 解析模块。通过分析页面,提取出所需的数据,在后续内容会做详细介绍。

    3) 保存数据函数

    该函数负责将抓取下来的数据保至数据库中,比如 MySQL、MongoDB 等,或者将其保存为文件格式,比如 csv、txt、excel 等。

    4) 入口函数

    入口函数充当整个爬虫程序的桥梁,通过调用不同的功能函数,实现数据的最终抓取。入口函数的主要任务是组织数据,比如要搜索的贴吧名、编码 url 参数、拼接 url 地址、定义文件保存路径。

    爬虫程序结构

    用面向对象的方法编写爬虫程序时,逻辑结构较为固定,总结如下:

    # 程序结构
    class xxxSpider(object):
        def __init__(self):
            # 定义常用变量,比如url或计数变量等
           
        def get_html(self):
            # 获取响应内容函数,使用随机User-Agent
       
        def parse_html(self):
            # 使用正则表达式来解析页面,提取数据
       
        def write_html(self):
            # 将提取的数据按要求保存,csv、MySQL数据库等
           
        def run(self):
            # 主函数,用来控制整体逻辑
           
    if __name__ == '__main__':
        # 程序开始运行时间
        spider = xxxSpider()
        spider.run()
    

    注意:掌握以上编程逻辑有助于您后续的学习。

    爬虫程序随机休眠

    在入口函数代码中,包含了以下代码:

    # 每爬取一个页面随机休眠1-2秒钟的时间
    time.sleep(random.randint(1,2))
    

    爬虫程序访问网站会非常快,这与正常人类的点击行为非常不符。因此,通过随机休眠可以使爬虫程序模仿成人类的样子点击网站,从而让网站不易察觉是爬虫访问网站,但这样做的代价就是影响程序的执行效率。

    聚焦爬虫是一种执行效率较低的程序,提升其性能,是业界一直关注的问题,由此也诞生了效率较高的 Python 爬虫框架 Scrapy。

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    Minimum Depth of Binary Tree leetcode java
    Maximum Depth of Binary Tree leetcode java
    Symmetric Tree leetcode java
    Same Tree leetcode java
    Binary Tree Postorder Traversal leetcode java
    Binary Tree Preorder Traversal leetcode java
    Binary Tree Inorder Traversal leetcode java
    Combinations leetcode java
    一键清除Centos iptables 防火墙所有规则
    阿里云centos7.7x64安装open,并配置ip转发和nat伪装
  • 原文地址:https://www.cnblogs.com/RioTian/p/15235023.html
Copyright © 2011-2022 走看看