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
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    ensp抓包只有蓝色的点闪烁没有跳出wireshark
    QuartusII 13.1编译通过,波形仿真报错Error: near "/": syntax error, unexpected '/', expecting ')'
    安装Multisim时出现No software will be installed or removed无法安装
    JavaScript实现页面实时显示时间
    css图片覆盖文字 点击显示文字
    php魔术方法——属性重载方法
    php魔术方法——构造函数和析构函数
    将含有父ID的列表转成树
    分割gbk中文出现乱码的问题解决
    json_encode如何防止汉字转义成unicode
  • 原文地址:https://www.cnblogs.com/RioTian/p/15235023.html
Copyright © 2011-2022 走看看