网络爬虫_网络爬虫实例 - CSDN
网络爬虫 订阅
网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。 展开全文
网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。
信息
外文名
web crawler
别    称
网络蜘蛛、蠕虫
作    用
抓取网站上的信息
中文名
网络爬虫
目    的
按要求获取万维网信息
算    法
网络拓扑、基于网页内容和基于用户访问行为三种算法
网络爬虫产生背景
随着网络的迅速发展,万维网成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战。搜索引擎(Search Engine),例如传统的通用搜索引擎AltaVista,Yahoo!和Google等,作为一个辅助人们检索信息的工具成为用户访问万维网的入口和指南。但是,这些通用性搜索引擎也存在着一定的局限性,如:(1)不同领域、不同背景的用户往往具有不同的检索目的和需求,通过搜索引擎所返回的结果包含大量用户不关心的网页。(2)通用搜索引擎的目标是尽可能大的网络覆盖率,有限的搜索引擎服务器资源与无限的网络数据资源之间的矛盾将进一步加深。(3)万维网数据形式的丰富和网络技术的不断发展,图片、数据库、音频、视频多媒体等不同数据大量出现,通用搜索引擎往往对这些信息含量密集且具有一定结构的数据无能为力,不能很好地发现和获取。(4)通用搜索引擎大多提供基于关键字的检索,难以支持根据语义信息提出的查询。 为了解决上述问题,定向抓取相关网页资源的聚焦爬虫应运而生。聚焦爬虫是一个自动下载网页的程序,它根据既定的抓取目标,有选择的访问万维网上的网页与相关的链接,获取所需要的信息。与通用爬虫(general purpose web crawler)不同,聚焦爬虫并不追求大的覆盖,而将目标定为抓取与某一特定主题内容相关的网页,为面向主题的用户查询准备数据资源。1 聚焦爬虫工作原理以及关键技术概述网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。另外,所有被爬虫抓取的网页将会被系统存贮,进行一定的分析、过滤,并建立索引,以便之后的查询和检索;对于聚焦爬虫来说,这一过程所得到的分析结果还可能对以后的抓取过程给出反馈和指导。 相对于通用网络爬虫,聚焦爬虫还需要解决三个主要问题:(1) 对抓取目标的描述或定义;(2) 对网页或数据的分析与过滤;(3) 对URL的搜索策略。
收起全文
精华内容
参与话题
  • 150讲轻松搞定Python网络爬虫

    万人学习 2020-10-13 16:23:00
    【为什么学爬虫?】        1、爬虫入手容易,但是深入较难,如何写出高效率的爬虫,如何写出灵活性高可扩展的爬虫都是一项技术活。另外在爬虫过程中,经常容易遇到被反爬虫,比如字体...
  • Python3网络爬虫快速入门实战解析

    万次阅读 多人点赞 2020-04-23 09:58:13
    请在电脑的陪同下,阅读本文。本文以实战为主,阅读过程...本文的实战内容有:网络小说下载(静态网站)、优美壁纸下载(动态网站)、爱奇艺VIP视频下载 PS:本文为Gitchat线上分享文章,该文章发布时间为2017年09月19日。

    转载请注明作者和出处: http://blog.csdn.net/c406495762
    Github代码获取:https://github.com/Jack-Cherish/python-spider
    Python版本: Python3.x
    运行平台: Windows
    IDE: Sublime text3


    更多教程,请查看:https://cuijiahua.com/blog/spider/

    一 前言

    **强烈建议:**请在电脑的陪同下,阅读本文。本文以实战为主,阅读过程如稍有不适,还望多加练习。
    本文的实战内容有:

    • 网络小说下载(静态网站)
    • 优美壁纸下载(动态网站)
    • 视频下载

    2020年,更多精彩内容,尽在微信公众号,欢迎您的关注:

    在这里插入图片描述

    二 网络爬虫简介

    网络爬虫,也叫网络蜘蛛(Web Spider)。它根据网页地址(URL)爬取网页内容,而网页地址(URL)就是我们在浏览器中输入的网站链接。比如:https://www.baidu.com/,它就是一个URL。

    在讲解爬虫内容之前,我们需要先学习一项写爬虫的必备技能:审查元素(如果已掌握,可跳过此部分内容)。

    1 审查元素

    在浏览器的地址栏输入URL地址,在网页处右键单击,找到检查。(不同浏览器的叫法不同,Chrome浏览器叫做检查,Firefox浏览器叫做查看元素,但是功能都是相同的)

    SouthEast

    我们可以看到,右侧出现了一大推代码,这些代码就叫做HTML。什么是HTML?举个容易理解的例子:我们的基因决定了我们的原始容貌,服务器返回的HTML决定了网站的原始容貌。

    SouthEast

    为啥说是原始容貌呢?因为人可以整容啊!扎心了,有木有?那网站也可以"整容"吗?可以!请看下图:

    SouthEast

    我能有这么多钱吗?显然不可能。我是怎么给网站"整容"的呢?就是通过修改服务器返回的HTML信息。我们每个人都是"整容大师",可以修改页面信息。我们在页面的哪个位置点击审查元素,浏览器就会为我们定位到相应的HTML位置,进而就可以在本地更改HTML信息。

    **再举个小例子:**我们都知道,使用浏览器"记住密码"的功能,密码会变成一堆小黑点,是不可见的。可以让密码显示出来吗?可以,只需给页面"动个小手术"!以淘宝为例,在输入密码框处右键,点击检查。

    SouthEast

    可以看到,浏览器为我们自动定位到了相应的HTML位置。将下图中的password属性值改为text属性值(直接在右侧代码处修改):

    SouthEast

    我们让浏览器记住的密码就这样显现出来了:

    SouthEast

    说这么多,什么意思呢?**浏览器就是作为客户端从服务器端获取信息,然后将信息解析,并展示给我们的。**我们可以在本地修改HTML信息,为网页"整容",但是我们修改的信息不会回传到服务器,服务器存储的HTML信息不会改变。刷新一下界面,页面还会回到原本的样子。这就跟人整容一样,我们能改变一些表面的东西,但是不能改变我们的基因。

    2 简单实例

    网络爬虫的第一步就是根据URL,获取网页的HTML信息。在Python3中,可以使用urllib.requestrequests进行网页爬取。

    • urllib库是python内置的,无需我们额外安装,只要安装了Python就可以使用这个库。
    • requests库是第三方库,需要我们自己安装。

    requests库强大好用,所以本文使用requests库获取网页的HTML信息。requests库的github地址:https://github.com/requests/requests

    (1) requests安装

    在cmd中,使用如下指令安装requests:

    pip install requests
    

    或者:

    easy_install requests
    

    (2) 简单实例

    requests库的基础方法如下:

    SouthEast

    官方中文教程地址:http://docs.python-requests.org/zh_CN/latest/user/quickstart.html

    requests库的开发者为我们提供了详细的中文教程,查询起来很方便。本文不会对其所有内容进行讲解,摘取其部分使用到的内容,进行实战说明。

    首先,让我们看下requests.get()方法,它用于向服务器发起GET请求,不了解GET请求没有关系。我们可以这样理解:get的中文意思是得到、抓住,那这个requests.get()方法就是从服务器得到、抓住数据,也就是获取数据。让我们看一个例子(以 www.gitbook.cn为例)来加深理解:

    # -*- coding:UTF-8 -*-
    import requests
    
    if __name__ == '__main__':
        target = 'http://gitbook.cn/'
        req = requests.get(url=target)
        print(req.text)
    

    requests.get()方法必须设置的一个参数就是url,因为我们得告诉GET请求,我们的目标是谁,我们要获取谁的信息。运行程序看下结果:

    SouthEast

    左侧是我们程序获得的结果,右侧是我们在www.gitbook.cn网站审查元素获得的信息。我们可以看到,我们已经顺利获得了该网页的HTML信息。这就是一个最简单的爬虫实例,可能你会问,我只是爬取了这个网页的HTML信息,有什么用呢?客官稍安勿躁,接下来进入我们的实战正文。


    三 爬虫实战

    1 小说下载

    (1) 实战背景

    小说网站-笔趣看:URL:http://www.biqukan.com/

    本次实战就是从该网站爬取并保存一本名为《一念永恒》的小说。

    (2) 小试牛刀

    我们先看下《一念永恒》小说的第一章内容,URL:http://www.biqukan.com/1_1094/5403177.html

    SouthEast

    我们先用已经学到的知识获取HTML信息试一试,编写代码如下:

    # -*- coding:UTF-8 -*-
    import requests
    
    if __name__ == '__main__':
        target = 'http://www.biqukan.com/1_1094/5403177.html'
        req = requests.get(url=target)
        print(req.text)
    

    运行代码,可以看到如下结果:

    SouthEast

    可以看到,我们很轻松地获取了HTML信息。但是,很显然,很多信息是我们不想看到的,我们只想获得如右侧所示的正文内容,我们不关心div、br这些html标签。如何把正文内容从这些众多的html标签中提取出来呢?这就是本次实战的主要内容。

    ###(3)Beautiful Soup

    **爬虫的第一步,获取整个网页的HTML信息,我们已经完成。接下来就是爬虫的第二步,解析HTML信息,提取我们感兴趣的内容。**对于本小节的实战,我们感兴趣的内容就是文章的正文。提取的方法有很多,例如使用正则表达式、Xpath、Beautiful Soup等。对于初学者而言,最容易理解,并且使用简单的方法就是使用Beautiful Soup提取感兴趣内容。

    Beautiful Soup的安装方法和requests一样,使用如下指令安装(也是二选一):

    • pip install beautifulsoup4
    • easy_install beautifulsoup4

    一个强大的第三方库,都会有一个详细的官方文档。我们很幸运,Beautiful Soup也是有中文的官方文档。

    URL:http://beautifulsoup.readthedocs.io/zh_CN/latest/

    同理,我会根据实战需求,讲解Beautiful Soup库的部分使用方法,更详细的内容,请查看官方文档。

    现在,我们使用已经掌握的审查元素方法,查看一下我们的目标页面,你会看到如下内容:

    SouthEast

    不难发现,文章的所有内容都放在了一个名为div的“东西下面”,这个"东西"就是html标签。HTML标签是HTML语言中最基本的单位,HTML标签是HTML最重要的组成部分。不理解,没关系,我们再举个简单的例子:

    一个女人的包包里,会有很多东西,她们会根据自己的习惯将自己的东西进行分类放好。镜子和口红这些会经常用到的东西,会归放到容易拿到的外侧口袋里。那些不经常用到,需要注意安全存放的证件会放到不容易拿到的里侧口袋里。

    html标签就像一个个“口袋”,每个“口袋”都有自己的特定功能,负责存放不同的内容。显然,上述例子中的div标签下存放了我们关心的正文内容。这个div标签是这样的:

    <div id="content", class="showtxt">
    

    细心的朋友可能已经发现,除了div字样外,还有id和class。id和class就是div标签的属性,content和showtxt是属性值,一个属性对应一个属性值。这东西有什么用?它是用来区分不同的div标签的,因为div标签可以有很多,我们怎么加以区分不同的div标签呢?就是通过不同的属性值。

    仔细观察目标网站一番,我们会发现这样一个事实:class属性为showtxt的div标签,独一份!这个标签里面存放的内容,是我们关心的正文部分。

    知道这个信息,我们就可以使用Beautiful Soup提取我们想要的内容了,编写代码如下:

    # -*- coding:UTF-8 -*-
    from bs4 import BeautifulSoup
    import requests
    if __name__ == "__main__":
         target = 'http://www.biqukan.com/1_1094/5403177.html'
         req = requests.get(url = target)
         html = req.text
         bf = BeautifulSoup(html)
         texts = bf.find_all('div', class_ = 'showtxt') print(texts)
    

    在解析html之前,我们需要创建一个Beautiful Soup对象。BeautifulSoup函数里的参数就是我们已经获得的html信息。然后我们使用find_all方法,获得html信息中所有class属性为showtxt的div标签。find_all方法的第一个参数是获取的标签名,第二个参数class_是标签的属性,为什么不是class,而带了一个下划线呢?因为python中class是关键字,为了防止冲突,这里使用class_表示标签的class属性,class_后面跟着的showtxt就是属性值了。看下我们要匹配的标签格式:

    <div id="content", class="showtxt">
    

    这样对应的看一下,是不是就懂了?可能有人会问了,为什么不是find_all(‘div’, id = ‘content’, class_ = ‘showtxt’)?这样其实也是可以的,属性是作为查询时候的约束条件,添加一个class_='showtxt’条件,我们就已经能够准确匹配到我们想要的标签了,所以我们就不必再添加id这个属性了。运行代码查看我们匹配的结果:

    SouthEast

    我们可以看到,我们已经顺利匹配到我们关心的正文内容,但是还有一些我们不想要的东西。比如div标签名,br标签,以及各种空格。怎么去除这些东西呢?我们继续编写代码:

    # -*- coding:UTF-8 -*-
    from bs4 import BeautifulSoup
    import requests
    if __name__ == "__main__":
         target = 'http://www.biqukan.com/1_1094/5403177.html'
         req = requests.get(url = target) html = req.text
         bf = BeautifulSoup(html)
         texts = bf.find_all('div', class_ = 'showtxt')
         print(texts[0].text.replace('\xa0'*8,'\n\n'))
    

    find_all匹配的返回的结果是一个列表。提取匹配结果后,使用text属性,提取文本内容,滤除br标签。随后使用replace方法,剔除空格,替换为回车进行分段。 在html中是用来表示空格的。replace(’\xa0’*8,’\n\n’)就是去掉下图的八个空格符号,并用回车代替:

    SouthEast

    程序运行结果如下:

    SouthEast

    可以看到,我们很自然的匹配到了所有正文内容,并进行了分段。我们已经顺利获得了一个章节的内容,要想下载正本小说,我们就要获取每个章节的链接。我们先分析下小说目录:

    URL:http://www.biqukan.com/1_1094/

    SouthEast

    通过审查元素,我们发现可以发现,这些章节都存放在了class属性为listmain的div标签下,选取部分html代码如下:

    <div class="listmain">
    <dl>
    <dt>《一念永恒》最新章节列表</dt>
    <dd><a href="/1_1094/15932394.html">第1027章 第十道门</a></dd>
    <dd><a href="/1_1094/15923072.html">第1026章 绝伦道法!</a></dd>
    <dd><a href="/1_1094/15921862.html">第1025章 长生灯!</a></dd>
    <dd><a href="/1_1094/15918591.html">第1024章 一目晶渊</a></dd>
    <dd><a href="/1_1094/15906236.html">第1023章 通天道门</a></dd>
    <dd><a href="/1_1094/15903775.html">第1022章 四大凶兽!</a></dd>
    <dd><a href="/1_1094/15890427.html">第1021章 鳄首!</a></dd>
    <dd><a href="/1_1094/15886627.html">第1020章 一触即发!</a></dd>
    <dd><a href="/1_1094/15875306.html">第1019章 魁祖的气息!</a></dd>
    <dd><a href="/1_1094/15871572.html">第1018章 绝望的魁皇城</a></dd>
    <dd><a href="/1_1094/15859514.html">第1017章 我还是恨你!</a></dd>
    <dd><a href="/1_1094/15856137.html">第1016章 从来没有世界之门!</a></dd>
    <dt>《一念永恒》正文卷</dt> <dd><a href="/1_1094/5386269.html">外传1 柯父。</a></dd>
    <dd><a href="/1_1094/5386270.html">外传2 楚玉嫣。</a></dd> <dd><a href="/1_1094/5386271.html">外传3 鹦鹉与皮冻。</a></dd>
    <dd><a href="/1_1094/5403177.html">第一章 他叫白小纯</a></dd> <dd><a href="/1_1094/5428081.html">第二章 火灶房</a></dd>
    <dd><a href="/1_1094/5433843.html">第三章 六句真言</a></dd> <dd><a href="/1_1094/5447905.html">第四章 炼灵</a></dd>
    </dl>
    </div>
    

    在分析之前,让我们先介绍一个概念:父节点、子节点、孙节点。<div></div>限定了<div>标签的开始和结束的位置,他们是成对出现的,有开始位置,就有结束位置。我们可以看到,在<div>标签包含<dl>标签,那这个<dl>标签就是<div>标签的子节点,<dl>标签又包含<dt>标签和<dd>标签,那么<dt>标签和<dd>标签就是<div>标签的孙节点。有点绕?那你记住这句话:谁包含谁,谁就是谁儿子!

    **他们之间的关系都是相对的。**比如对于<dd>标签,它的子节点是<a>标签,它的父节点是<dl>标签。这跟我们人是一样的,上有老下有小。

    看到这里可能有人会问,这有好多<dd>标签和<a>标签啊!不同的<dd>标签,它们是什么关系啊?显然,兄弟姐妹喽!我们称它们为兄弟结点。
    好了,概念明确清楚,接下来,让我们分析一下问题。我们看到每个章节的名字存放在了<a>标签里面。<a>标签还有一个href属性。这里就不得不提一下<a>标签的定义了,<a>标签定义了一个超链接,用于从一张页面链接到另一张页面。<a> 标签最重要的属性是 href 属性,它指示链接的目标。

    我们将之前获得的第一章节的URL和<a> 标签对比看一下:

    http://www.biqukan.com/1_1094/5403177.html
    <a href="/1_1094/5403177.html">第一章 他叫白小纯</a>
    

    不难发现,<a> 标签中href属性存放的属性值/1_1094/5403177.html是章节URLhttp://www.biqukan.com/1_1094/5403177.html的后半部分。其他章节也是如此!那这样,我们就可以根据<a>标签的href属性值获得每个章节的链接和名称了。

    总结一下:小说每章的链接放在了class属性为listmain的<div>标签下的<a>标签中。链接具体位置放在html->body->div->dl->dd->a的href属性中。先匹配class属性为listmain的<div>标签,再匹配<a>标签。编写代码如下:

    # -*- coding:UTF-8 -*-
    from bs4 import BeautifulSoup
    import requests
    if __name__ == "__main__":
         target = 'http://www.biqukan.com/1_1094/'
         req = requests.get(url = target)
         html = req.text
         div_bf = BeautifulSoup(html)
         div = div_bf.find_all('div', class_ = 'listmain')
         print(div[0])
    

    还是使用find_all方法,运行结果如下:

    SouthEast

    很顺利,接下来再匹配每一个<a>标签,并提取章节名和章节文章。如果我们使用Beautiful Soup匹配到了下面这个<a>标签,如何提取它的href属性和<a>标签里存放的章节名呢?

    <a href="/1_1094/5403177.html">第一章 他叫白小纯</a>
    

    方法很简单,对Beautiful Soup返回的匹配结果a,使用a.get(‘href’)方法就能获取href的属性值,使用a.string就能获取章节名,编写代码如下:

    # -*- coding:UTF-8 -*-
    from bs4 import BeautifulSoup
    import requests
    if __name__ == "__main__":
         server = 'http://www.biqukan.com/'
         target = 'http://www.biqukan.com/1_1094/'
         req = requests.get(url = target) html = req.text
         div_bf = BeautifulSoup(html)
         div = div_bf.find_all('div', class_ = 'listmain')
         a_bf = BeautifulSoup(str(div[0]))
         a = a_bf.find_all('a')
         for each in a:
              print(each.string, server + each.get('href'))
    

    因为find_all返回的是一个列表,里边存放了很多的<a>标签,所以使用for循环遍历每个<a>标签并打印出来,运行结果如下。

    SouthEast

    最上面匹配的一千多章的内容是最新更新的12章节的链接。这12章内容会和下面的重复,所以我们要滤除,除此之外,还有那3个外传,我们也不想要。这些都简单地剔除就好。

    ###(3)整合代码

    每个章节的链接、章节名、章节内容都有了。接下来就是整合代码,将获得内容写入文本文件存储就好了。编写代码如下:

    # -*- coding:UTF-8 -*-
    from bs4 import BeautifulSoup
    import requests, sys
    
    """
    类说明:下载《笔趣看》网小说《一念永恒》
    Parameters:
        无
    Returns:
        无
    Modify:
        2017-09-13
    """
    class downloader(object):
    
        def __init__(self):
            self.server = 'http://www.biqukan.com/'
            self.target = 'http://www.biqukan.com/1_1094/'
            self.names = []            #存放章节名
            self.urls = []            #存放章节链接
            self.nums = 0            #章节数
    
        """
        函数说明:获取下载链接
        Parameters:
            无
        Returns:
            无
        Modify:
            2017-09-13
        """
        def get_download_url(self):
            req = requests.get(url = self.target)
            html = req.text
            div_bf = BeautifulSoup(html)
            div = div_bf.find_all('div', class_ = 'listmain')
            a_bf = BeautifulSoup(str(div[0]))
            a = a_bf.find_all('a')
            self.nums = len(a[15:])                                #剔除不必要的章节,并统计章节数
            for each in a[15:]:
                self.names.append(each.string)
                self.urls.append(self.server + each.get('href'))
    
        """
        函数说明:获取章节内容
        Parameters:
            target - 下载连接(string)
        Returns:
            texts - 章节内容(string)
        Modify:
            2017-09-13
        """
        def get_contents(self, target):
            req = requests.get(url = target)
            html = req.text
            bf = BeautifulSoup(html)
            texts = bf.find_all('div', class_ = 'showtxt')
            texts = texts[0].text.replace('\xa0'*8,'\n\n')
            return texts
    
        """
        函数说明:将爬取的文章内容写入文件
        Parameters:
            name - 章节名称(string)
            path - 当前路径下,小说保存名称(string)
            text - 章节内容(string)
        Returns:
            无
        Modify:
            2017-09-13
        """
        def writer(self, name, path, text):
            write_flag = True
            with open(path, 'a', encoding='utf-8') as f:
                f.write(name + '\n')
                f.writelines(text)
                f.write('\n\n')
    
    if __name__ == "__main__":
        dl = downloader()
        dl.get_download_url()
        print('《一年永恒》开始下载:')
        for i in range(dl.nums):
            dl.writer(dl.names[i], '一念永恒.txt', dl.get_contents(dl.urls[i]))
            sys.stdout.write("  已下载:%.3f%%" %  float(i/dl.nums) + '\r')
            sys.stdout.flush()
        print('《一年永恒》下载完成')
    

    很简单的程序,单进程跑,没有开进程池。下载速度略慢,喝杯茶休息休息吧。代码运行效果如下图所示:

    SouthEast

    2 优美壁纸下载

    ###(1)实战背景

    已经会爬取文字了,是不是感觉爬虫还是蛮好玩的呢?接下来,让我们进行一个进阶实战,了解一下反爬虫。

    URL:https://unsplash.com/

    SouthEast

    看一看这些优美的壁纸,这个网站的名字叫做Unsplash,免费高清壁纸分享网是一个坚持每天分享高清的摄影图片的站点,每天更新一张高质量的图片素材,全是生活中的景象作品,清新的生活气息图片可以作为桌面壁纸也可以应用于各种需要的环境。

    看到这么优美的图片,我的第一反应就是想收藏一些,作为知乎文章的题图再好不过了。每张图片我都很喜欢,批量下载吧,不多爬,就下载50张好了。

    ###(2)实战进阶

    我们已经知道了每个html标签都有各自的功能。<a>标签存放一下超链接,图片存放在哪个标签里呢?html规定,图片统统给我放到<img>标签中!既然这样,我们截取就Unsplash网站中的一个<img>标签,分析一下:

    <img alt="Snow-capped mountain slopes under blue sky" src="https://images.unsplash.com/photo-1428509774491-cfac96e12253?dpr=1&amp;auto=compress,format&amp;fit=crop&amp;w=360&amp;h=240&amp;q=80&amp;cs=tinysrgb&amp;crop=" class="cV68d" style="width: 220px; height: 147px;">
    

    可以看到,<img>标签有很多属性,有alt、src、class、style属性,其中src属性存放的就是我们需要的图片保存地址,我们根据这个地址就可以进行图片的下载。

    那么,让我们先捋一捋这个过程:

    • 使用requeusts获取整个网页的HTML信息;
    • 使用Beautiful Soup解析HTML信息,找到所有<img>标签,提取src属性,获取图片存放地址;
    • 根据图片存放地址,下载图片。

    我们信心满满地按照这个思路爬取Unsplash试一试,编写代码如下:

    # -*- coding:UTF-8 -*-
    import requests
    if __name__ == '__main__':
         target = 'https://unsplash.com/'
         req = requests.get(url=target)
         print(req.text)
    

    按照我们的设想,我们应该能找到很多<img>标签。但是我们发现,除了一些<script>标签和一些看不懂的代码之外,我们一无所获,一个<img>标签都没有!跟我们在网站审查元素的结果完全不一样,这是为什么?

    SouthEast

    **答案就是,这个网站的所有图片都是动态加载的!**网站有静态网站和动态网站之分,上一个实战爬取的网站是静态网站,而这个网站是动态网站,动态加载有一部分的目的就是为了反爬虫。

    对于什么是动态加载,你可以这样理解:我们知道化妆术学的好,贼厉害,可以改变一个人的容貌。相应的,动态加载用的好,也贼厉害,可以改变一个网站的容貌。

    动态网站使用动态加载常用的手段就是通过调用JavaScript来实现的。怎么实现JavaScript动态加载,我们不必深究,我们只要知道,动态加载的JavaScript脚本,就像化妆术需要用的化妆品,五花八门。有粉底、口红、睫毛膏等等,它们都有各自的用途。动态加载的JavaScript脚本也一样,一个动态加载的网站可能使用很多JavaScript脚本,我们只要找到负责动态加载图片的JavaScript脚本,不就找到我们需要的链接了吗?

    对于初学者,我们不必看懂JavaScript执行的内容是什么,做了哪些事情,因为我们有强大的抓包工具,它自然会帮我们分析。这个强大的抓包工具就是Fiddler:

    URL:http://www.telerik.com/fiddler

    PS:也可以使用浏览器自带的Networks,但是我更推荐这个软件,因为它操作起来更高效。

    安装方法很简单,傻瓜式安装,一直下一步即可,对于经常使用电脑的人来说,应该没有任何难度。

    这个软件的使用方法也很简单,打开软件,然后用浏览器打开我们的目标网站,以Unsplash为例,抓包结果如下:

    SouthEast

    我们可以看到,上图左侧红框处是我们的GET请求的地址,就是网站的URL,右下角是服务器返回的信息,我们可以看到,这些信息也是我们上一个程序获得的信息。这个不是我们需要的链接,我们继续往下看。

    SouthEast

    我们发现上图所示的就是一个JavaScript请求,看右下侧服务器返回的信息是一个json格式的数据。这里面,就有我们需要的内容。我们局部放大看一下:

    SouthEast

    这是Fiddler右侧的信息,上面是请求的Headers信息,包括这个Javascript的请求地 址:http://unsplash.com/napi/feeds/home,其他信息我们先不管,我们看看下面的内容。里面有很多图片的信息,包括图片的id,图片的大小,图片的链接,还有下一页的地址。这个脚本以json格式存储传输的数据,json格式是一种轻量级的数据交换格式,起到封装数据的作用,易于人阅读和编写,同时也易于机器解析和生成。这么多链接,可以看到图片的链接有很多,根据哪个链接下载图片呢?先别急,让我们继续分析:

    SouthEast

    在这个网站,我们可以按这个按钮进行图片下载。我们抓包分下下这个动作,看看发送了哪些请求。

    https://unsplash.com/photos/1PrQ2mHW-Fo/download?force=true
    https://unsplash.com/photos/JX7nDtafBcU/download?force=true
    https://unsplash.com/photos/HCVbP3zqX4k/download?force=true
    

    通过Fiddler抓包,我们发现,点击不同图片的下载按钮,GET请求的地址都是不同的。但是它们很有规律,就是中间有一段代码是不一样的,其他地方都一样。中间那段代码是不是很熟悉?没错,它就是我们之前抓包分析得到json数据中的照片的id。我们只要解析出每个照片的id,就可以获得图片下载的请求地址,然后根据这个请求地址,我们就可以下载图片了。那么,现在的首要任务就是解析json数据了。

    json格式的数据也是分层的。可以看到next_page里存放的是下一页的请求地址,很显然Unsplash下一页的内容,也是动态加载的。在photos下面的id里,存放着图片的id,这个就是我们需要获得的图片id号。

    怎么编程提取这些json数据呢?我们也是分步完成:

    • 获取整个json数据
    • 解析json数据

    编写代码,尝试获取json数据:

    # -*- coding:UTF-8 -*-
    import requests
    if __name__ == '__main__':
         target = 'http://unsplash.com/napi/feeds/home'
         req = requests.get(url=target) print(req.text)
    

    很遗憾,程序报错了,问题出在哪里?通过错误信息,我们可以看到SSL认证错误,SSL认证是指客户端到服务器端的认证。一个非常简单的解决这个认证错误的方法就是设置requests.get()方法的verify参数。这个参数默认设置为True,也就是执行认证。我们将其设置为False,绕过认证不就可以了?

    SouthEast

    有想法就要尝试,编写代码如下:

    # -*- coding:UTF-8 -*-
    import requests
    if __name__ == '__main__':
         target = 'http://unsplash.com/napi/feeds/home'
         req = requests.get(url=target, verify=False)
         print(req.text)
    

    认证问题解决了,又有新问题了:

    SouthEast

    可以看到,我们GET请求又失败了,这是为什么?这个网站反爬虫的手段除了动态加载,还有一个反爬虫手段,那就是验证Request Headers。接下来,让我们分析下这个Requests Headers:

    SouthEast

    我截取了Fiddler的抓包信息,可以看到Requests Headers里又很多参数,有Accept、Accept-Encoding、Accept-Language、DPR、User-Agent、Viewport-Width、accept-version、Referer、x-unsplash-client、authorization、Connection、Host。它们都是什么意思呢?

    专业的解释能说的太多,我挑重点:

    • User-Agent:这里面存放浏览器的信息。可以看到上图的参数值,它表示我是通过Windows的Chrome浏览器,访问的这个服务器。如果我们不设置这个参数,用Python程序直接发送GET请求,服务器接受到的User-Agent信息就会是一个包含python字样的User-Agent。如果后台设计者验证这个User-Agent参数是否合法,不让带Python字样的User-Agent访问,这样就起到了反爬虫的作用。这是一个最简单的,最常用的反爬虫手段。

    • Referer:这个参数也可以用于反爬虫,它表示这个请求是从哪发出的。可以看到我们通过浏览器访问网站,这个请求是从https://unsplash.com/,这个地址发出的。如果后台设计者,验证这个参数,对于不是从这个地址跳转过来的请求一律禁止访问,这样就也起到了反爬虫的作用。

    • authorization:这个参数是基于AAA模型中的身份验证信息允许访问一种资源的行为。在我们用浏览器访问的时候,服务器会为访问者分配这个用户ID。如果后台设计者,验证这个参数,对于没有用户ID的请求一律禁止访问,这样就又起到了反爬虫的作用。

    Unsplash是根据哪个参数反爬虫的呢?根据我的测试,是authorization。我们只要通过程序手动添加这个参数,然后再发送GET请求,就可以顺利访问了。怎么什么设置呢?还是requests.get()方法,我们只需要添加headers参数即可。编写代码如下:

    # -*- coding:UTF-8 -*-
    import requests
    if __name__ == '__main__':
         target = 'http://unsplash.com/napi/feeds/home'
         headers = {'authorization':'your Client-ID'}
         req = requests.get(url=target, headers=headers, verify=False)
         print(req.text)
    

    headers参数值是通过字典传入的。记得将上述代码中your Client-ID换成诸位自己抓包获得的信息。代码运行结果如下:

    SouthEast

    皇天不负有心人,可以看到我们已经顺利获得json数据了,里面有next_page和照片的id。接下来就是解析json数据。根据我们之前分析可知,next_page放在了json数据的最外侧,照片的id放在了photos->id里。我们使用json.load()方法解析数据,编写代码如下:

    # -*- coding:UTF-8 -*-
    import requests, json
    if __name__ == '__main__':
         target = 'http://unsplash.com/napi/feeds/home'
         headers = {'authorization':'your Client-ID'}
         req = requests.get(url=target, headers=headers, verify=False)
         html = json.loads(req.text)
         next_page = html['next_page']
         print('下一页地址:',next_page)
         for each in html['photos']:
              print('图片ID:',each['id'])
    

    解析json数据很简单,跟字典操作一样,就是字典套字典。json.load()里面的参数是原始的json格式的数据。程序运行结果如下:

    SouthEast

    图片的ID已经获得了,再通过字符串处理一下,就生成了我们需要的图片下载请求地址。根据这个地址,我们就可以下载图片了。下载方式,使用直接写入文件的方法。

    ###(3)整合代码

    每次获取链接加一个1s延时,因为人在浏览页面的时候,翻页的动作不可能太快。我们要让我们的爬虫尽量友好一些。

    # -*- coding:UTF-8 -*-
    import requests, json, time, sys
    from contextlib import closing
    
    class get_photos(object):
    
        def __init__(self):
            self.photos_id = []
            self.download_server = 'https://unsplash.com/photos/xxx/download?force=trues'
            self.target = 'http://unsplash.com/napi/feeds/home'
            self.headers = {'authorization':'Client-ID c94869b36aa272dd62dfaeefed769d4115fb3189a9d1ec88ed457207747be626'}
    
        """
        函数说明:获取图片ID
        Parameters:
            无
        Returns:
            无
        Modify:
            2017-09-13
        """   
        def get_ids(self):
            req = requests.get(url=self.target, headers=self.headers, verify=False)
            html = json.loads(req.text)
            next_page = html['next_page']
            for each in html['photos']:
                self.photos_id.append(each['id'])
            time.sleep(1)
            for i in range(5):
                req = requests.get(url=next_page, headers=self.headers, verify=False)
                html = json.loads(req.text)
                next_page = html['next_page']
                for each in html['photos']:
                    self.photos_id.append(each['id'])
                time.sleep(1)
    
    
        """
        函数说明:图片下载
        Parameters:
            无
        Returns:
            无
        Modify:
            2017-09-13
        """   
        def download(self, photo_id, filename):
            headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36'}
            target = self.download_server.replace('xxx', photo_id)
            with closing(requests.get(url=target, stream=True, verify = False, headers = self.headers)) as r:
                with open('%d.jpg' % filename, 'ab+') as f:
                    for chunk in r.iter_content(chunk_size = 1024):
                        if chunk:
                            f.write(chunk)
                            f.flush()
    
    if __name__ == '__main__':
        gp = get_photos()
        print('获取图片连接中:')
        gp.get_ids()
        print('图片下载中:')
        for i in range(len(gp.photos_id)):
            print('  正在下载第%d张图片' % (i+1))
            gp.download(gp.photos_id[i], (i+1))
    

    下载速度还行,有的图片下载慢是因为图片太大。可以看到右侧也打印了一些警报信息,这是因为我们没有进行SSL验证。

    SouthEast

    学会了爬取图片,简单的动态加载的网站也难不倒你了。赶快试试国内的一些图片网站吧!

    3 视频下载

    视频下载教程,请到这里查看:

    https://cuijiahua.com/blog/2017/10/spider_tutorial_1.html

    四 总结

    • 本次Chat讲解的实战内容,均仅用于学习交流,请勿用于任何商业用途!
    • 爬虫时效性低,同样的思路过了一个月,甚至一周可能无法使用,但是爬取思路都是如此,完全可以自行分析。
    • 本次实战代码,均已上传我的Github,欢迎Follow、Star:https://github.com/Jack-Cherish/python-spider
    • 如有问题,请留言。如有错误,还望指正,谢谢!
    展开全文
  • Python 网络爬虫入门详解

    万次阅读 多人点赞 2018-09-25 18:15:29
    什么是网络爬虫    网络爬虫又称网络蜘蛛,是指按照某种规则在网络上爬取所需内容的脚本程序。众所周知,每个网页通常包含其他网页的入口,网络爬虫则通过一个网址依次进入其他网址获取所需内容。 优先申明:...

    什么是网络爬虫

     

           网络爬虫又称网络蜘蛛,是指按照某种规则在网络上爬取所需内容的脚本程序。众所周知,每个网页通常包含其他网页的入口,网络爬虫则通过一个网址依次进入其他网址获取所需内容。

    优先申明:我们使用的python编译环境为PyCharm

     

    一、首先一个网络爬虫的组成结构:

    • 爬虫调度程序(程序的入口,用于启动整个程序)
    • url管理器(用于管理未爬取得url及已经爬取过的url)
    • 网页下载器(用于下载网页内容用于分析)
    • 网页解析器(用于解析下载的网页,获取新的url和所需内容)
    • 网页输出器(用于把获取到的内容以文件的形式输出)

     

    二、编写网络爬虫

    (1)准备所需库

     我们需要准备一款名为BeautifulSoup(网页解析)的开源库,用于对下载的网页进行解析,我们是用的是PyCharm编译环境所以可以直接下载该开源库。

     

    步骤如下:

    选择File->Settings

     

    打开Project:PythonProject下的Project interpreter

     

    点击加号添加新的库

     

    输入bs4选择bs4点击Install Packge进行下载

     

    (2)编写爬虫调度程序

        这里的bike_spider是项目名称引入的四个类分别对应下面的四段代码url管理器,url下载器,url解析器,url输出器。

    # 爬虫调度程序
    from bike_spider import url_manager, html_downloader, html_parser, html_outputer
    
    
    # 爬虫初始化
    class SpiderMain(object):
        def __init__(self):
            self.urls = url_manager.UrlManager()
            self.downloader = html_downloader.HtmlDownloader()
            self.parser = html_parser.HtmlParser()
            self.outputer = html_outputer.HtmlOutputer()
    
        def craw(self, my_root_url):
            count = 1
            self.urls.add_new_url(my_root_url)
            while self.urls.has_new_url():
                try:
                    new_url = self.urls.get_new_url()
                    print("craw %d : %s" % (count, new_url))
                    # 下载网页
                    html_cont = self.downloader.download(new_url)
                    # 解析网页
                    new_urls, new_data = self.parser.parse(new_url, html_cont)
                    self.urls.add_new_urls(new_urls)
                    # 网页输出器收集数据
                    self.outputer.collect_data(new_data)
                    if count == 10:
                        break
                    count += 1
                except:
                    print("craw failed")
    
            self.outputer.output_html()
    
    
    if __name__ == "__main__":
        root_url = "http://baike.baidu.com/item/Python/407313"
        obj_spider = SpiderMain()
        obj_spider.craw(root_url)

     

    (3)编写url管理器

    我们把已经爬取过的url和未爬取的url分开存放以便我们不会重复爬取某些已经爬取过的网页。

    # url管理器
    class UrlManager(object):
        def __init__(self):
            self.new_urls = set()
            self.old_urls = set()
    
        def add_new_url(self, url):
            if url is None:
                return
            if url not in self.new_urls and url not in self.old_urls:
                self.new_urls.add(url)
    
        def add_new_urls(self, urls):
            if urls is None or len(urls) == 0:
                return
            for url in urls:
                self.new_urls.add(url)
    
        def get_new_url(self):
            # pop方法会帮我们获取一个url并且移除它
            new_url = self.new_urls.pop()
            self.old_urls.add(new_url)
            return new_url
    
        def has_new_url(self):
            return len(self.new_urls) != 0

     

    (4)编写网页下载器

    通过网络请求来下载页面

    # 网页下载器
    import urllib.request
    
    
    class HtmlDownloader(object):
    
        def download(self, url):
            if url is None:
                return None
            response = urllib.request.urlopen(url)
            # code不为200则请求失败
            if response.getcode() != 200:
                return None
            return response.read()

     

    (5)编写网页解析器

    对网页进行解析时我们需要知道我们要查询的内容都有哪些特征,我们可以打开一个网页点击右键审查元素来了解我们所查内容的共同之处。

    # 网页解析器
    import re
    from bs4 import BeautifulSoup
    from urllib.parse import urljoin
    
    
    class HtmlParser(object):
    
        def parse(self, page_url, html_cont):
            if page_url is None or html_cont is None:
                return
            soup = BeautifulSoup(html_cont, "html.parser", from_encoding="utf-8")
            new_urls = self._get_new_urls(page_url, soup)
            new_data = self._get_new_data(page_url, soup)
            return new_urls, new_data
    
        def _get_new_data(self, page_url, soup):
            res_data = {"url": page_url}
            # 获取标题
            title_node = soup.find("dd", class_="lemmaWgt-lemmaTitle-title").find("h1")
            res_data["title"] = title_node.get_text()
            summary_node = soup.find("div", class_="lemma-summary")
            res_data["summary"] = summary_node.get_text()
            return res_data
    
        def _get_new_urls(self, page_url, soup):
            new_urls = set()
            # 查找出所有符合下列条件的url
            links = soup.find_all("a", href=re.compile(r"/item/"))
            for link in links:
                new_url = link['href']
                # 获取到的url不完整,学要拼接
                new_full_url = urljoin(page_url, new_url)
                new_urls.add(new_full_url)
            return new_urls

     

    (6)编写网页输出器

    输出的格式有很多种,我们选择以html的形式输出,这样我们可以的到一个html页面。

    # 网页输出器
    class HtmlOutputer(object):
    
        def __init__(self):
            self.datas = []
    
        def collect_data(self, data):
            if data is None:
                return
            self.datas.append(data)
    
        # 我们以html表格形式进行输出
        def output_html(self):
            fout = open("output.html", "w", encoding='utf-8')
            fout.write("<html>")
            fout.write("<meta charset='utf-8'>")
            fout.write("<body>")
            # 以表格输出
            fout.write("<table>")
            for data in self.datas:
                # 一行
                fout.write("<tr>")
                # 每个单元行的内容
                fout.write("<td>%s</td>" % data["url"])
                fout.write("<td>%s</td>" % data["title"])
                fout.write("<td>%s</td>" % data["summary"])
                fout.write("</tr>")
            fout.write("</table>")
            fout.write("</body>")
            fout.write("</html>")
            # 输出完毕后一定要关闭输出器
            fout.close()
    

     

    写在末尾

           注意:网页经常发生变化,我们需要根据网页的变化动态修改我们的代码来获得我们所需要的内容。

           这只是一个简单的网络爬虫,如果需要完善其功能我们需要考虑更多问题。

    爬虫入门后可以看一下爬虫如何模拟登陆Python爬虫模拟登陆

     

    展开全文
  • 特色1:案例驱动-围绕两大完整的Python网络爬虫实战开发案例:IT电子书下载网络爬虫和股票交易数据下载网络爬虫展开。 特色2:实战开发-全面剖析实战案例Python电子书下载网络爬虫业务流程、程序逻辑、语法规则和...
  • 网络爬虫基本原理

    千次阅读 2018-01-16 05:53:05
    网络爬虫是捜索引擎抓取系统的重要组成部分。爬虫的主要目的是将互联网上的网页下载到本地形成一个或联网内容的镜像备份。这篇博客主要对爬虫以及抓取系统进行一个简单的概述。 一、网络爬虫的基本结构及工作流程...

     网络爬虫是捜索引擎抓取系统的重要组成部分。爬虫的主要目的是将互联网上的网页下载到本地形成一个或联网内容的镜像备份。这篇博客主要对爬虫以及抓取系统进行一个简单的概述。

    一、网络爬虫的基本结构及工作流程

        一个通用的网络爬虫的框架如图所示:

        网络爬虫的基本工作流程如下:

        1.首先选取一部分精心挑选的种子URL;

        2.将这些URL放入待抓取URL队列;

        3.从待抓取URL队列中取出待抓取在URL,解析DNS,并且得到主机的ip,并将URL对应的网页下载下来,存储进已下载网页库中。此外,将这些URL放进已抓取URL队列。

        4.分析已抓取URL队列中的URL,分析其中的其他URL,并且将URL放入待抓取URL队列,从而进入下一个循环。

    二、从爬虫的角度对互联网进行划分

        对应的,可以将互联网的所有页面分为五个部分:

        1.已下载未过期网页

        2.已下载已过期网页:抓取到的网页实际上是互联网内容的一个镜像与备份,互联网是动态变化的,一部分互联网上的内容已经发生了变化,这时,这部分抓取到的网页就已经过期了。

        3.待下载网页:也就是待抓取URL队列中的那些页面

        4.可知网页:还没有抓取下来,也没有在待抓取URL队列中,但是可以通过对已抓取页面或者待抓取URL对应页面进行分析获取到的URL,认为是可知网页。

        5.还有一部分网页,爬虫是无法直接抓取下载的。称为不可知网页。

    三、抓取策略

        在爬虫系统中,待抓取URL队列是很重要的一部分。待抓取URL队列中的URL以什么样的顺序排列也是一个很重要的问题,因为这涉及到先抓取那个页面,后抓取哪个页面。而决定这些URL排列顺序的方法,叫做抓取策略。下面重点介绍几种常见的抓取策略:

        1.深度优先遍历策略

    深度优先遍历策略是指网络爬虫会从起始页开始,一个链接一个链接跟踪下去,处理完这条线路之后再转入下一个起始页,继续跟踪链接。我们以下面的图为例:

        遍历的路径:A-F-G  E-H-I B C D

        2.宽度优先遍历策略

        宽度优先遍历策略的基本思路是,将新下载网页中发现的链接直接插入待抓取URL队列的末尾。也就是指网络爬虫会先抓取起始网页中链接的所有网页,然后再选择其中的一个链接网页,继续抓取在此网页中链接的所有网页。还是以上面的图为例:

        遍历路径:A-B-C-D-E-F G H I

        3.反向链接数策略

        反向链接数是指一个网页被其他网页链接指向的数量。反向链接数表示的是一个网页的内容受到其他人的推荐的程度。因此,很多时候搜索引擎的抓取系统会使用这个指标来评价网页的重要程度,从而决定不同网页的抓取先后顺序。

        在真实的网络环境中,由于广告链接、作弊链接的存在,反向链接数不能完全等他我那个也的重要程度。因此,搜索引擎往往考虑一些可靠的反向链接数。

        4.Partial PageRank策略

        Partial PageRank算法借鉴了PageRank算法的思想:对于已经下载的网页,连同待抓取URL队列中的URL,形成网页集合,计算每个页面的PageRank值,计算完之后,将待抓取URL队列中的URL按照PageRank值的大小排列,并按照该顺序抓取页面。

        如果每次抓取一个页面,就重新计算PageRank值,一种折中方案是:每抓取K个页面后,重新计算一次PageRank值。但是这种情况还会有一个问题:对于已经下载下来的页面中分析出的链接,也就是我们之前提到的未知网页那一部分,暂时是没有PageRank值的。为了解决这个问题,会给这些页面一个临时的PageRank值:将这个网页所有入链传递进来的PageRank值进行汇总,这样就形成了该未知页面的PageRank值,从而参与排序。下面举例说明:

        5.OPIC策略策略

        该算法实际上也是对页面进行一个重要性打分。在算法开始前,给所有页面一个相同的初始现金(cash)。当下载了某个页面P之后,将P的现金分摊给所有从P中分析出的链接,并且将P的现金清空。对于待抓取URL队列中的所有页面按照现金数进行排序。

        6.大站优先策略

        对于待抓取URL队列中的所有网页,根据所属的网站进行分类。对于待下载页面数多的网站,优先下载。这个策略也因此叫做大站优先策略。 

    四、更新策略
        互联网是实时变化的,具有很强的动态性。网页更新策略主要是决定何时更新之前已经下载过的页面。常见的更新策略又以下三种:
        1.历史参考策略
        顾名思义,根据页面以往的历史更新数据,预测该页面未来何时会发生变化。一般来说,是通过泊松过程进行建模进行预测。
        2.用户体验策略
        尽管搜索引擎针对于某个查询条件能够返回数量巨大的结果,但是用户往往只关注前几页结果。因此,抓取系统可以优先更新那些现实在查询结果前几页中的网页,而后再更新那些后面的网页。这种更新策略也是需要用到历史信息的。用户体验策略保留网页的多个历史版本,并且根据过去每次内容变化对搜索质量的影响,得出一个平均值,用这个值作为决定何时重新抓取的依据。
        3.聚类抽样策略
        前面提到的两种更新策略都有一个前提:需要网页的历史信息。这样就存在两个问题:第一,系统要是为每个系统保存多个版本的历史信息,无疑增加了很多的系统负担;第二,要是新的网页完全没有历史信息,就无法确定更新策略。
        这种策略认为,网页具有很多属性,类似属性的网页,可以认为其更新频率也是类似的。要计算某一个类别网页的更新频率,只需要对这一类网页抽样,以他们的更新周期作为整个类别的更新周期。基本思路如图:

            
    五、分布式抓取系统结构
        一般来说,抓取系统需要面对的是整个互联网上数以亿计的网页。单个抓取程序不可能完成这样的任务。往往需要多个抓取程序一起来处理。一般来说抓取系统往往是一个分布式的三层结构。如图所示:

        最下一层是分布在不同地理位置的数据中心,在每个数据中心里有若干台抓取服务器,而每台抓取服务器上可能部署了若干套爬虫程序。这就构成了一个基本的分布式抓取系统。
        对于一个数据中心内的不同抓去服务器,协同工作的方式有几种:
        1.主从式(Master-Slave)
        主从式基本结构如图所示:

        对于主从式而言,有一台专门的Master服务器来维护待抓取URL队列,它负责每次将URL分发到不同的Slave服务器,而Slave服务器则负责实际的网页下载工作。Master服务器除了维护待抓取URL队列以及分发URL之外,还要负责调解各个Slave服务器的负载情况。以免某些Slave服务器过于清闲或者劳累。
        这种模式下,Master往往容易成为系统瓶颈。
        2.对等式(Peer to Peer)
        对等式的基本结构如图所示:

        在这种模式下,所有的抓取服务器在分工上没有不同。每一台抓取服务器都可以从待抓取在URL队列中获取URL,然后对该URL的主域名的hash值H,然后计算H mod m(其中m是服务器的数量,以上图为例,m为3),计算得到的数就是处理该URL的主机编号。
        举例:假设对于URL www.baidu.com,计算器hash值H=8,m=3,则H mod m=2,因此由编号为2的服务器进行该链接的抓取。假设这时候是0号服务器拿到这个URL,那么它将该URL转给服务器2,由服务器2进行抓取。
        这种模式有一个问题,当有一台服务器死机或者添加新的服务器,那么所有URL的哈希求余的结果就都要变化。也就是说,这种方式的扩展性不佳。针对这种情况,又有一种改进方案被提出来。这种改进的方案是一致性哈希法来确定服务器分工。其基本结构如图所示:

        一致性哈希将URL的主域名进行哈希运算,映射为一个范围在0-232之间的某个数。而将这个范围平均的分配给m台服务器,根据URL主域名哈希运算的值所处的范围判断是哪台服务器来进行抓取。
        如果某一台服务器出现问题,那么本该由该服务器负责的网页则按照顺时针顺延,由下一台服务器进行抓取。这样的话,及时某台服务器出现问题,也不会影响其他的工作。

    补充:

     开源爬虫
     DataparkSearch是一个在GNU GPL许可下发布的爬虫搜索引擎
     GNU Wget是一个在GPL许可下,使用C语言编写的命令行式的爬虫。它主要用于网络服务器和FTP服务器的镜像
     Heritrix是一个互联网档案馆级的爬虫,设计的目标为对大型网络的大部分内容的定期存档快照,是使用java编写的。
     Ht://Dig在它和索引引擎中包括了一个网页爬虫。
     HTTrack用网络爬虫创建网络站点镜像,以便离线观看。它使用C语言编写,在GPL许可下发行。
     ICDL Crawler是一个用C++编写,跨平台的网络爬虫。它仅仅使用空闲的CPU资源,在ICDL标准上抓取整个站点。
     JSpider是一个在GPL许可下发行的,高度可配置的,可定制的网络爬虫引擎。
     LLarbin由Sebastien Ailleret开发;
     Webtools4larbin由Andreas Beder开发;
     Methabot是一个使用C语言编写的高速优化的,使用命令行方式运行的,在2-clause BSD许可下发布的网页检索器。它的主要的特性是高可配置性,模块化;它检索的目标可以是本地文件系统,HTTP或者FTP。
     Nutch是一个使用java编写,在Apache许可下发行的爬虫。它可以用来连接Lucene的全文检索套件;
     Pavuk是一个在GPL许可下发行的,使用命令行的WEB站点镜像工具,可以选择使用X11的图形界面。与wget和httprack相比,他有一系列先进的特性,如以正则表达式为基础的文件过滤规则和文件创建规则。
     WebVac是斯坦福WebBase项目使用的一个爬虫。
     WebSPHINX(Miller and Bharat, 1998)是一个由java类库构成的,基于文本的搜索引擎。它使用多线程进行网页检索,html解析,拥有一个图形用户界面用来设置开始的种子URL和抽取下载的数据;
     WIRE-网络信息检索环境(Baeza-Yates 和 Castillo, 2002)是一个使用C++编写,在GPL许可下发行的爬虫,内置了几种页面下载安排的策略,还有一个生成报告和统计资料的模块,所以,它主要用于网络特征的描述;
     LWP:RobotUA(Langheinrich,2004)是一个在Perl5许可下发行的,可以优异的完成并行任务的 Perl类库构成的机器人。
     Web Crawler是一个为.net准备的开放源代码的网络检索器(C#编写)。
     Sherlock Holmes收集和检索本地和网络上的文本类数据(文本文件,网页),该项目由捷克门户网站中枢(Czech web portal Centrum)赞助并且主用商用于这里;它同时也使用在。
     YaCy是一个基于P2P网络的免费的分布式搜索引擎(在GPL许可下发行);
     Ruya是一个在广度优先方面表现优秀,基于等级抓取的开放源代码的网络爬虫。在英语和日语页面的抓取表现良好,它在GPL许可下发行,并且完全使用Python编写。按照robots.txt有一个延时的单网域延时爬虫。
     Universal Information Crawler快速发展的网络爬虫,用于检索存储和分析数据;
     Agent Kernel,当一个爬虫抓取时,用来进行安排,并发和存储的java框架。
     是一个使用C#编写,需要SQL Server 2005支持的,在GPL许可下发行的多功能的开源的机器人。它可以用来下载,检索,存储包括电子邮件地址,文件,超链接,图片和网页在内的各种数据。
     Dine是一个多线程的java的http客户端。它可以在LGPL许可下进行二次开发。
    网络爬虫的组成
    在网络爬虫的系统框架中,主过程由控制器,解析器,资源库三部分组成。控制器的主要工作是负责给多线程中的各个爬虫线程分配工作任务。解析器的主要工作是下载网页,进行页面的处理,主要是将一些JS脚本标签、CSS代码内容、空格字符、HTML标签等内容处理掉,爬虫的基本工作是由解析器完成。资源库是用来存放下载到的网页资源,一般都采用大型的数据库存储,如Oracle数据库,并对其建立索引。

    展开全文
  • 01网络爬虫实现原理详解不同类型的网络爬虫,其实现原理也是不同的,但这些实现原理中,会存在很多共性。在此,我们将以两种典型的网络爬虫为例(即通用网络爬虫和聚焦网络爬虫)...
        

    01 

    网络爬虫实现原理详解


    不同类型的网络爬虫,其实现原理也是不同的,但这些实现原理中,会存在很多共性。在此,我们将以两种典型的网络爬虫为例(即通用网络爬虫和聚焦网络爬虫),分别为大家讲解网络爬虫的实现原理。

    1. 通用网络爬虫

    首先我们来看通用网络爬虫的实现原理。通用网络爬虫的实现原理及过程可以简要概括如下(见图3-1)。

    640?wx_fmt=png

    ▲图3-1 通用网络爬虫的实现原理及过程

    1. 获取初始的URL。初始的URL地址可以由用户人为地指定,也可以由用户指定的某个或某几个初始爬取网页决定。

    2. 根据初始的URL爬取页面并获得新的URL。获得初始的URL地址之后,首先需要爬取对应URL地址中的网页,爬取了对应的URL地址中的网页后,将网页存储到原始数据库中,并且在爬取网页的同时,发现新的URL地址,同时将已爬取的URL地址存放到一个URL列表中,用于去重及判断爬取的进程。

    3. 将新的URL放到URL队列中。在第2步中,获取了下一个新的URL地址之后,会将新的URL地址放到URL队列中。

    4. 从URL队列中读取新的URL,并依据新的URL爬取网页,同时从新网页中获取新URL,并重复上述的爬取过程。

    5. 满足爬虫系统设置的停止条件时,停止爬取。在编写爬虫的时候,一般会设置相应的停止条件。如果没有设置停止条件,爬虫则会一直爬取下去,一直到无法获取新的URL地址为止,若设置了停止条件,爬虫则会在停止条件满足时停止爬取。

    以上就是通用网络爬虫的实现过程与基本原理,接下来,我们为大家分析聚焦网络爬虫的基本原理及其实现过程。

    2. 聚焦网络爬虫

    聚焦网络爬虫,由于其需要有目的地进行爬取,所以对于通用网络爬虫来说,必须要增加目标的定义和过滤机制,具体来说,此时,其执行原理和过程需要比通用网络爬虫多出三步,即目标的定义、无关链接的过滤、下一步要爬取的URL地址的选取等,如图3-2所示。

    640?wx_fmt=png

    ▲图3-2 聚焦网络爬虫的基本原理及其实现过程

    • 对爬取目标的定义和描述。在聚焦网络爬虫中,我们首先要依据爬取需求定义好该聚焦网络爬虫爬取的目标,以及进行相关的描述。

    • 获取初始的URL。

    • 根据初始的URL爬取页面,并获得新的URL。

    • 从新的URL中过滤掉与爬取目标无关的链接。因为聚焦网络爬虫对网页的爬取是有目的性的,所以与目标无关的网页将会被过滤掉。同时,也需要将已爬取的URL地址存放到一个URL列表中,用于去重和判断爬取的进程。

    • 将过滤后的链接放到URL队列中。

    • 从URL队列中,根据搜索算法,确定URL的优先级,并确定下一步要爬取的URL地址。在通用网络爬虫中,下一步爬取哪些URL地址,是不太重要的,但是在聚焦网络爬虫中,由于其具有目的性,故而下一步爬取哪些URL地址相对来说是比较重要的。对于聚焦网络爬虫来说,不同的爬取顺序,可能导致爬虫的执行效率不同,所以,我们需要依据搜索策略来确定下一步需要爬取哪些URL地址。

    • 从下一步要爬取的URL地址中,读取新的URL,然后依据新的URL地址爬取网页,并重复上述爬取过程。

    • 满足系统中设置的停止条件时,或无法获取新的URL地址时,停止爬行。

    • 现在我们初步掌握了网络爬虫的实现原理以及相应的工作流程,下面来了解网络爬虫的爬行策略。


    02 

    爬行策略


    在网络爬虫爬取的过程,在待爬取的URL列表中,可能有很多URL地址,那么这些URL地址,爬虫应该先爬取哪个,后爬取哪个呢?

    在通用网络爬虫中,虽然爬取的顺序并不是那么重要,但是在其他很多爬虫中,比如聚焦网络爬虫中,爬取的顺序非常重要,而爬取的顺序,一般由爬行策略决定。我们将为大家介绍一些常见的爬行策略。

    爬行策略主要有深度优先爬行策略、广度优先爬行策略、大站优先策略、反链策略、其他爬行策略等。下面我们将分别进行介绍。

    如图3-3所示,假设有一个网站,ABCDEFG分别为站点下的网页,图中箭头表示网页的层次结构。


    640?wx_fmt=png

    ▲图3-3 某网站的网页层次结构示意图


    假如此时网页ABCDEFG都在爬行队列中,那么按照不同的爬行策略,其爬取的顺序是不同的。

    比如,如果按照深度优先爬行策略去爬取的话,那么此时会首先爬取一个网页,然后将这个网页的下层链接依次深入爬取完再返回上一层进行爬取。

    所以,若按深度优先爬行策略,图3-3中的爬行顺序可以是:A → D → E → B → C → F → G。

    如果按照广度优先的爬行策略去爬取的话,那么此时首先会爬取同一层次的网页,将同一层次的网页全部爬取完后,在选择下一个层次的网页去爬行,比如,上述的网站中,如果按照广度优先的爬行策略去爬取的话,爬行顺序可以是:A→B→C→D→E→F→G。

    除了以上两种爬行策略之外,我们还可以采用大站爬行策略。我们可以按对应网页所属的站点进行归类,如果某个网站的网页数量多,那么我们则将其称为大站,按照这种策略,网页数量越多的网站越大,然后,优先爬取大站中的网页URL地址。

    一个网页的反向链接数,指的是该网页被其他网页指向的次数,这个次数在一定程度上代表着该网页被其他网页的推荐次数。所以,如果按反链策略去爬行的话,那么哪个网页的反链数量越多,则哪个网页将被优先爬取。

    但是,在实际情况中,如果单纯按反链策略去决定一个网页的优先程度的话,那么可能会出现大量的作弊情况。比如,做一些垃圾站群,并将这些网站互相链接,如果这样的话,每个站点都将获得较高的反链,从而达到作弊的目的。

    作为爬虫项目方,我们当然不希望受到这种作弊行为的干扰,所以,如果采用反向链接策略去爬取的话,一般会考虑可靠的反链数。

    除了以上这些爬行策略,在实际中还有很多其他的爬行策略,比如OPIC策略、Partial PageRank策略等。

    640?wx_fmt=jpeg

    03 

    网页更新策略


    一个网站的网页经常会更新,作为爬虫方,在网页更新后,我们则需要对这些网页进行重新爬取,那么什么时候去爬取合适呢?如果网站更新过慢,而爬虫爬取得过于频繁,则必然会增加爬虫及网站服务器的压力,若网站更新较快,但是爬虫爬取的时间间隔较长,则我们爬取的内容版本会过老,不利于新内容的爬取。

    显然,网站的更新频率与爬虫访问网站的频率越接近,则效果越好,当然,爬虫服务器资源有限的时候,此时爬虫也需要根据对应策略,让不同的网页具有不同的更新优先级,优先级高的网页更新,将获得较快的爬取响应。

    具体来说,常见的网页更新策略主要有3种:用户体验策略、历史数据策略、聚类分析策略等,以下我们将分别进行讲解。

    在搜索引擎查询某个关键词的时候,会出现一个排名结果,在排名结果中,通常会有大量的网页,但是,大部分用户都只会关注排名靠前的网页,所以,在爬虫服务器资源有限的情况下,爬虫会优先更新排名结果靠前的网页。

    这种更新策略,我们称之为用户体验策略,那么在这种策略中,爬虫到底何时去爬取这些排名结果靠前的网页呢?此时,爬取中会保留对应网页的多个历史版本,并进行对应分析,依据这多个历史版本的内容更新、搜索质量影响、用户体验等信息,来确定对这些网页的爬取周期。

    除此之外,我们还可以使用历史数据策略来确定对网页更新爬取的周期。比如,我们可以依据某一个网页的历史更新数据,通过泊松过程进行建模等手段,预测该网页下一次更新的时间,从而确定下一次对该网页爬取的时间,即确定更新周期。

    以上两种策略,都需要历史数据作为依据。有的时候,若一个网页为新网页,则不会有对应的历史数据,并且,如果要依据历史数据进行分析,则需要爬虫服务器保存对应网页的历史版本信息,这无疑给爬虫服务器带来了更多的压力和负担。

    如果想要解决这些问题,则需要采取新的更新策略。比较常用的是聚类分析策略。那么什么是聚类分析策略呢?

    在生活中,相信大家对分类已经非常熟悉,比如我们去商场,商场中的商品一般都分好类了,方便顾客去选购相应的商品,此时,商品分类的类别是固定的,是已经拟定好的。

    但是,假如商品的数量巨大,事先无法对其进行分类,或者说,根本不知道将会拥有哪些类别的商品,此时,我们应该如何解决将商品归类的问题呢?

    这时候我们可以用聚类的方式解决,依据商品之间的共性进行相应分析,将共性较多的商品聚为一类,此时,商品聚集成的类的数目是不一定的,但是能保证的是,聚在一起的商品之间一定有某种共性,即依据“物以类聚”的思想去实现。

    同样,在我们的聚类算法中,也会有类似的分析过程。

    将聚类分析算法运用在爬虫对网页的更新上,我们可以这样做,如图3-4所示。

    640?wx_fmt=png

    ▲图3-4 网页更新策略之聚类算法


    • 首先,经过大量的研究发现,网页可能具有不同的内容,但是一般来说,具有类似属性的网页,其更新频率类似。这是聚类分析算法运用在爬虫网页的更新上的一个前提指导思想。

    • 有了1中的指导思想后,我们可以首先对海量的网页进行聚类分析,在聚类之后,会形成多个类,每个类中的网页具有类似的属性,即一般具有类似的更新频率。

    • 聚类完成后,我们可以对同一个聚类中的网页进行抽样,然后求该抽样结果的平均更新值,从而确定对每个聚类的爬行频率。

    以上,就是使用爬虫爬取网页的时候,常见的3种更新策略,我们掌握了其算法思想后,在后续我们进行爬虫的实际开发的时候,编写出来的爬虫执行效率会更高,并且执行逻辑会更合理。


    04 

    网页分析算法


    在搜索引擎中,爬虫爬取了对应的网页之后,会将网页存储到服务器的原始数据库中,之后,搜索引擎会对这些网页进行分析并确定各网页的重要性,即会影响用户检索的排名结果。

    所以在此,我们需要对搜索引擎的网页分析算法进行简单了解。

    搜索引擎的网页分析算法主要分为3类:基于用户行为的网页分析算法、基于网络拓扑的网页分析算法、基于网页内容的网页分析算法。接下来我们分别对这些算法进行讲解。

    1. 基于用户行为的网页分析算法

    基于用户行为的网页分析算法是比较好理解的。这种算法中,会依据用户对这些网页的访问行为,对这些网页进行评价,比如,依据用户对该网页的访问频率、用户对网页的访问时长、用户的单击率等信息对网页进行综合评价。

    2. 基于网络拓扑的网页分析算法

    基于网络拓扑的网页分析算法是依靠网页的链接关系、结构关系、已知网页或数据等对网页进行分析的一种算法,所谓拓扑,简单来说即结构关系的意思。

    基于网络拓扑的网页分析算法,同样主要可以细分为3种类型:基于网页粒度的分析算法、基于网页块粒度的分析算法、基于网站粒度的分析算法。

    PageRank算法是一种比较典型的基于网页粒度的分析算法。相信很多朋友都听过Page-Rank算法,它是谷歌搜索引擎的核心算法,简单来说,它会根据网页之间的链接关系对网页的权重进行计算,并可以依靠这些计算出来的权重,对网页进行排名。

    当然,具体的算法细节有很多,在此不展开讲解。除了PageRank算法之外,HITS算法也是一种常见的基于网页粒度的分析算法。

    640?wx_fmt=jpeg

    基于网页块粒度的分析算法,也是依靠网页间链接关系进行计算的,但计算规则有所不同。

    我们知道,在一个网页中通常会包含多个超链接,但一般其指向的外部链接中并不是所有的链接都与网站主题相关,或者说,这些外部链接对该网页的重要程度是不一样的,所以若要基于网页块粒度进行分析,则需要对一个网页中的这些外部链接划分层次,不同层次的外部链接对于该网页来说,其重要程度不同。

    这种算法的分析效率和准确率,会比传统的算法好一些。

    基于网站粒度的分析算法,也与PageRank算法类似,但是,如果采用基于网站粒度进行分析,相应的,会使用SiteRank算法。即此时我们会划分站点的层次和等级,而不再具体地计算站点下的各个网页的等级。

    所以其相对于基于网页粒度的算法来说,则更加简单高效,但是会带来一些缺点,比如精确度不如基于网页粒度的分析算法精确。

    3. 基于网页内容的网页分析算法

    在基于网页内容的网页分析算法中,会依据网页的数据、文本等网页内容特征,对网页进行相应的评价。

    以上,我简单为大家介绍了搜索引擎中的网页分析算法,我们学习爬虫,需要对这些算法进行相应的了解。


    05 

    身份识别


    在爬虫对网页爬取的过程中,爬虫必然需要访问对应的网页,正规的爬虫一般会告诉对应网页的网站站长其爬虫身份。网站的管理员则可以通过爬虫告知的身份信息对爬虫的身份进行识别,我们称这个过程为爬虫的身份识别过程。

    那么,爬虫应该如何告知网站站长自己的身份呢?

    一般地,爬虫在对网页进行爬取访问的时候,会通过HTTP请求中的User Agent字段告知自己的身份信息。一般爬虫访问一个网站的时候,首先会根据该站点下的Robots.txt文件来确定可爬取的网页范围,Robots协议是需要网络爬虫共同遵守的协议,对于一些禁止的URL地址,网络爬虫则不应爬取访问。

    同时,如果爬虫在爬取某一个站点时陷入死循环,造成该站点的服务压力过大,如果有正确的身份设置,那么该站点的站长则可以想办法联系到该爬虫方,然后停止对应的爬虫程序。

    当然,有些爬虫会伪装成其他爬虫或浏览器去爬取网站,以获得一些额外数据,或者有些爬虫,会无视Robots协议的限制而任意爬取。从技术的角度来说,这些行为实现起来不难,但是这些行为是我们不提倡的,因为只有共同遵守一个良好的网络规则,才能够达到爬虫方和站点服务方的双赢。

    640?wx_fmt=jpeg


    06 

    网络爬虫实现技术


    通过前面的学习,我们基本上对爬虫的基本理论知识有了比较全面的了解,那么,如果我们要实现网络爬虫技术,要开发自己的网络爬虫,可以使用哪些语言进行开发呢?

    开发网络爬虫的语言有很多,常见的语言有:Python、Java、PHP、Node.JS、C++、Go语言等。以下我们将分别介绍一下用这些语言写爬虫的特点:

    • Python:爬虫框架非常丰富,并且多线程的处理能力较强,并且简单易学、代码简洁,优点很多。

    • Java:适合开发大型爬虫项目。

    • PHP:后端处理很强,代码很简洁,模块也较丰富,但是并发能力相对来说较弱。

    • Node.JS:支持高并发与多线程处理。

    • C++:运行速度快,适合开发大型爬虫项目,成本较高。

    • Go语言:同样高并发能力非常强。


    总结

    1、聚焦网络爬虫,由于其需要有目的地进行爬取,所以对于通用网络爬虫来说,必须要增加目标的定义和过滤机制,具体来说,此时,其执行原理和过程需要比通用网络爬虫多出3步,即目标的定义、无关链接的过滤、下一步要爬取的URL地址的选取。

    2、常见的网页更新策略主要有3种:用户体验策略、历史数据策略、聚类分析策略。

    3、聚类分析可以依据商品之间的共性进行相应的处理,将共性较多的商品聚为一类。

    4、在爬虫对网页爬取的过程中,爬虫必然需要访问对应的网页,此时,正规的爬虫一般会告诉对应网页的网站站长其爬虫身份。网站的管理员则可以通过爬虫告知的身份信息对爬虫的身份进行识别,我们称这个过程为爬虫的身份识别过程。

    5、开发网络爬虫的语言有很多,常见的语言有Python、Java、PHP、Node.JS、C++、Go语言等。

    本文摘编自《精通Python网络爬虫:核心技术、框架与项目实战》

    640?wx_fmt=jpeg


    《精通Python网络爬虫:核心技术、框架与项目实战》

    点击书籍封面查看详情


    640?wx_fmt=png

    扫码或者点击阅读原文购买


    关于作者

    韦玮,资深网络爬虫技术专家、大数据专家和软件开发工程师,从事大型软件开发与技术服务多年,精通Python技术,在Python网络爬虫、Python机器学习、Python数据分析与挖掘、Python Web开发等多个领域都有丰富的实战经验。 

    编辑推荐

    本书详细讲解了如何基于Python从零开始构建一个成熟的网络爬虫解决方案的完整过程,以及业界主流爬虫技术的原理与实战案例,同时也引入了作者个人的经验与思考,非常有价值。本书循序渐进的内容组织结构,相信无论是新手还是老手,均能很好地阅读和吸收。 

    640?wx_fmt=png

    扫码或者点击阅读原文购买

    640?wx_fmt=gif


    码书商店是CSDN专为我们的用户建立的一个商店,这里提供大量的技术书籍(书籍都是由出版社直接邮寄,不用担心是否正版),除了书籍我们也提供生活类的相关产品,如耳机、键盘等,或者你们如果有需求也可以联系码书商店的客服或者在公众号下留言你们需要的产品,我们尽量满足大家需求哦。

    作为码书商店的运营人员,诚邀你们进入我们的“CSDN码书福利群”,群里会不定时的给大家赠送书籍、优惠券等,有书籍推荐或者物流方面信息也可群里咨询~目前群已满100人,需要加群的请加微信号“xthmily”,拉你入群哦~

    640?wx_fmt=png


    点击“阅读原文”

    展开全文
  • 爬虫(一)网络爬虫/相关工具与知识

    万次阅读 多人点赞 2018-06-02 16:12:59
    网络爬虫 网络爬虫(web crawler), 以前经常称为网络蜘蛛(spider), 是按照一定的规则自动浏览万维网并获取信息的机器人程序(或叫脚本), 曾经被广泛的应用于互联网搜索引擎. 使用过互联网和浏览器的人都知道, 网页中...
  • 爬虫系列(一) 网络爬虫简介

    万次阅读 多人点赞 2019-03-11 18:26:41
    最近博主在学习网络爬虫的相关技术(基于 Python 语言),作为一个学习的总结,打算用博客记录下来,也希望和大家分享一下自己在学习过程中的点点滴滴,话不多说,让我们马上开始吧 ^_^
  • 通过网络爬虫采集大数据

    万次阅读 2019-06-13 21:27:59
    网络数据采集是指通过网络爬虫或网站公开 API 等方式从网站上获取数据信息。该方法可以将非结构化数据从网页中抽取出来,将其存储为统一的本地数据文件,并以结构化的方式存储。它支持图片、音频、视频等文件或附件...
  • python爬虫从入门到精通全套

    万次阅读 2016-12-09 14:29:45
    https://zhuanlan.zhihu.com/p/21479334
  • python爬虫教程大全

    万次阅读 多人点赞 2013-10-14 12:47:20
    关于python爬虫这方面知识,在网络上有一些教程、文章,很有价值,能够带领新手快速入门。在这里我把自己学习时找到的一些教程列出来,与大家一起分享,...《[Python]网络爬虫(一):抓取网页的含义和URL基本构成》
  • Python爬虫的用途

    万次阅读 多人点赞 2018-08-16 14:02:03
    Python爬虫是用Python编程语言实现的网络爬虫,主要用于网络数据的抓取和处理,相比于其他语言,Python是一门非常适合开发网络爬虫的编程语言,大量内置包,可以轻松实现网络爬虫功能。 Python爬虫可以做的事情很多...
  • 如何判断爬虫采集内容是否违法?

    万次阅读 2018-01-12 21:02:59
     随着大数据和人工智能的火爆,网络爬虫也被大家熟知起来;随之也出现一个问题,网络爬虫违法吗?符合道德吗?本文将详细介绍网络爬虫是否违法,希望帮助你解决爬虫是否违法带来的困扰。 网络爬虫大多数情况都不...
  • 网络爬虫简单实例

    万次阅读 2018-05-13 12:24:16
    京东:亚马逊:更改了头部信息,模拟浏览器对网站进行访问百度/360通过输入关键词获得搜索信息:只需要将其中的keyword替换为自己搜索的关键词即可 网络图片的爬取:将图片从url这个网址下载到本地的root的路径下&...
  • 什么是爬虫?有哪些用途

    万次阅读 2018-07-11 11:44:51
    数据的来源:去第三方的公司购买数据(比如企查查)去免费的数据网站下载数据... 分为通用爬虫(搜索引擎、聚焦爬虫(12306抢票) 、增量式网络爬虫(Incremental Web Crawler)和深层网络爬虫爬虫获取的数据的用途...
  • 导读:网络爬虫也叫做网络机器人,可以代替人们自动地在互联网中进行数据信息的采集与整理。在大数据时代,信息的采集是一项重要的工作,如果单纯靠人力进行信息采集,不仅低效繁琐,...
  • 精通Python网络爬虫-书籍介绍

    万次阅读 2017-04-10 12:34:40
    精通Python网络爬虫是韦玮老师最新书籍,主要定位于Python网络爬虫入门、进阶(初中级)的从业人员。
  • 网络爬虫是什么

    万次阅读 多人点赞 2017-09-18 14:50:17
    作为一家大数据公司的运营小编,经常会有人问我“诶?...网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或
  •  网络爬虫又称网络蜘蛛、网络蚂蚁、网络机器人等,可以自动化浏览网络中的信息,当然浏览信息的时候需要按照我们制定的规则进行,这些规则我们称之为网络爬虫算法。使用Python可以很方便地编写出爬虫程序,进行...
  • 用c语言写一个网络爬虫

    万次阅读 2016-09-08 18:19:40
    写一个网络爬虫写一个网络爬虫,来获取一个网站上感兴趣的信息。最基本的模型 就是图。每个页面看作一个节点,若页面A有到达页面B的链接,则添加一条由A到B的单向边。爬虫要遍历这张图。 遍历这张图 广度优先搜索...
1 2 3 4 5 ... 20
收藏数 97,251
精华内容 38,900
关键字:

网络爬虫