爬虫_爬虫入门 - 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的搜索策略。
收起全文
精华内容
参与话题
  • 爬虫微课5小时 Python学习路线

    万人学习 2020-01-13 11:05:39
    Python爬虫技术视频教程,该课程每堂课都有一个作业,包含的项目案例有家长帮142600条数据爬取与分析,全球天气数据抓取与分析,淘宝商品信息数据众数分析,12306余票查询,python软件打包exe与发布。学完此课程能让...
  • 手把手教你利用爬虫爬网页(Python代码)

    万次阅读 多人点赞 2019-05-14 14:51:58
    本文主要分为两个部分:一部分是网络爬虫的概述,帮助大家详细了解网络爬虫;另一部分是HTTP请求的Python实现,帮助大家了解Python中实现HTTP请求的各种方式,以...
        

    640?wx_fmt=jpeg

    本文主要分为两个部分:一部分是网络爬虫的概述,帮助大家详细了解网络爬虫;另一部分是HTTP请求的Python实现,帮助大家了解Python中实现HTTP请求的各种方式,以便具备编写HTTP网络程序的能力。


    01

    网络爬虫概述


    接下来从网络爬虫的概念、用处与价值和结构等三个方面,让大家对网络爬虫有一个基本的了解。

    1. 网络爬虫及其应用

    随着网络的迅速发展,万维网成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战,网络爬虫应运而生。网络爬虫(又被称为网页蜘蛛、网络机器人),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。下面通过图3-1展示一下网络爬虫在互联网中起到的作用:


    640?wx_fmt=png

    ▲图3-1 网络爬虫


    网络爬虫按照系统结构和实现技术,大致可以分为以下几种类型:通用网络爬虫、聚焦网络爬虫、增量式网络爬虫、深层网络爬虫。实际的网络爬虫系统通常是几种爬虫技术相结合实现的。

    搜索引擎(Search Engine),例如传统的通用搜索引擎baidu、Yahoo和Google等,是一种大型复杂的网络爬虫,属于通用性网络爬虫的范畴。但是通用性搜索引擎存在着一定的局限性:

    1. 不同领域、不同背景的用户往往具有不同的检索目的和需求,通用搜索引擎所返回的结果包含大量用户不关心的网页。

    2. 通用搜索引擎的目标是尽可能大的网络覆盖率,有限的搜索引擎服务器资源与无限的网络数据资源之间的矛盾将进一步加深。

    3. 万维网数据形式的丰富和网络技术的不断发展,图片、数据库、音频、视频多媒体等不同数据大量出现,通用搜索引擎往往对这些信息含量密集且具有一定结构的数据无能为力,不能很好地发现和获取。

    4. 通用搜索引擎大多提供基于关键字的检索,难以支持根据语义信息提出的查询。

    为了解决上述问题,定向抓取相关网页资源的聚焦爬虫应运而生。

    聚焦爬虫是一个自动下载网页的程序,它根据既定的抓取目标,有选择地访问万维网上的网页与相关的链接,获取所需要的信息。与通用爬虫不同,聚焦爬虫并不追求大的覆盖,而将目标定为抓取与某一特定主题内容相关的网页,为面向主题的用户查询准备数据资源。

    说完了聚焦爬虫,接下来再说一下增量式网络爬虫。增量式网络爬虫是指对已下载网页采取增量式更新和只爬行新产生的或者已经发生变化网页的爬虫,它能够在一定程度上保证所爬行的页面是尽可能新的页面。

    和周期性爬行和刷新页面的网络爬虫相比,增量式爬虫只会在需要的时候爬行新产生或发生更新的页面,并不重新下载没有发生变化的页面,可有效减少数据下载量,及时更新已爬行的网页,减小时间和空间上的耗费,但是增加了爬行算法的复杂度和实现难度。

    例如:想获取赶集网的招聘信息,以前爬取过的数据没有必要重复爬取,只需要获取更新的招聘数据,这时候就要用到增量式爬虫。

    最后说一下深层网络爬虫。Web页面按存在方式可以分为表层网页和深层网页。表层网页是指传统搜索引擎可以索引的页面,以超链接可以到达的静态网页为主构成的Web页面。深层网络是那些大部分内容不能通过静态链接获取的、隐藏在搜索表单后的,只有用户提交一些关键词才能获得的Web页面。

    例如用户登录或者注册才能访问的页面。可以想象这样一个场景:爬取贴吧或者论坛中的数据,必须在用户登录后,有权限的情况下才能获取完整的数据。

    2. 网络爬虫结构

    下面用一个通用的网络爬虫结构来说明网络爬虫的基本工作流程,如图3-4所示。


    640?wx_fmt=png

    ▲图3-4 网络爬虫结构

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

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

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

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

    4. 分析已抓取URL队列中的URL,从已下载的网页数据中分析出其他URL,并和已抓取的URL进行比较去重,最后将去重过的URL放入待抓取URL队列,从而进入下一个循环。

    02

    HTTP请求的Python实现


    通过上面的网络爬虫结构,我们可以看到读取URL、下载网页是每一个爬虫必备而且关键的功能,这就需要和HTTP请求打交道。接下来讲解Python中实现HTTP请求的三种方式:urllib2/urllib、httplib/urllib以及Requests。

    1. urllib2/urllib实现

    urllib2和urllib是Python中的两个内置模块,要实现HTTP功能,实现方式是以urllib2为主,urllib为辅。

    1.1 首先实现一个完整的请求与响应模型

    urllib2提供一个基础函数urlopen,通过向指定的URL发出请求来获取数据。最简单的形式是:

    import urllib2
    response=urllib2.urlopen('http://www.zhihu.com')
    html=response.read()
    print html

    其实可以将上面对http://www.zhihu.com的请求响应分为两步,一步是请求,一步是响应,形式如下:

    import urllib2
    # 请求
    request=urllib2.Request('http://www.zhihu.com')
    # 响应
    response = urllib2.urlopen(request)
    html=response.read()
    print html

    上面这两种形式都是GET请求,接下来演示一下POST请求,其实大同小异,只是增加了请求数据,这时候用到了urllib。示例如下:

    import urllib
    import urllib2
    url = 'http://www.xxxxxx.com/login'
    postdata = {'username' : 'qiye',
        'password' : 'qiye_pass'}
    # info 需要被编码为urllib2能理解的格式,这里用到的是urllib
    data = urllib.urlencode(postdata)
    req = urllib2.Request(url, data)
    response = urllib2.urlopen(req)
    html = response.read()

    但是有时会出现这种情况:即使POST请求的数据是对的,但是服务器拒绝你的访问。这是为什么呢?问题出在请求中的头信息,服务器会检验请求头,来判断是否是来自浏览器的访问,这也是反爬虫的常用手段。

    1.2 请求头headers处理

    将上面的例子改写一下,加上请求头信息,设置一下请求头中的User-Agent域和Referer域信息。

    import urllib
    import urllib2
    url = 'http://www.xxxxxx.com/login'
    user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
    referer='http://www.xxxxxx.com/'
    postdata = {'username' : 'qiye',
        'password' : 'qiye_pass'}
    # 将user_agent,referer写入头信息
    headers={'User-Agent':user_agent,'Referer':referer}
    data = urllib.urlencode(postdata)
    req = urllib2.Request(url, data,headers)
    response = urllib2.urlopen(req)
    html = response.read()

    也可以这样写,使用add_header来添加请求头信息,修改如下:

    import urllib
    import urllib2
    url = 'http://www.xxxxxx.com/login'
    user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
    referer='http://www.xxxxxx.com/'
    postdata = {'username' : 'qiye',
        'password' : 'qiye_pass'}
    data = urllib.urlencode(postdata)
    req = urllib2.Request(url)
    # 将user_agent,referer写入头信息
    req.add_header('User-Agent',user_agent)
    req.add_header('Referer',referer)
    req.add_data(data)
    response = urllib2.urlopen(req)
    html = response.read()

    对有些header要特别留意,服务器会针对这些header做检查,例如:

    • User-Agent:有些服务器或Proxy会通过该值来判断是否是浏览器发出的请求。

    • Content-Type:在使用REST接口时,服务器会检查该值,用来确定HTTP Body中的内容该怎样解析。在使用服务器提供的RESTful或SOAP服务时,Content-Type设置错误会导致服务器拒绝服务。常见的取值有:application/xml(在XML RPC,如RESTful/SOAP调用时使用)、application/json(在JSON RPC调用时使用)、application/x-www-form-urlencoded(浏览器提交Web表单时使用)。

    • Referer:服务器有时候会检查防盗链。

    1.3 Cookie处理

    urllib2对Cookie的处理也是自动的,使用CookieJar函数进行Cookie的管理。如果需要得到某个Cookie项的值,可以这么做:

    import urllib2
    import cookielib
    cookie = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
    response = opener.open('http://www.zhihu.com')
    for item in cookie:
        print item.name+':'+item.value

    但是有时候会遇到这种情况,我们不想让urllib2自动处理,我们想自己添加Cookie的内容,可以通过设置请求头中的Cookie域来做:

    import  urllib2
    opener = urllib2.build_opener()
    opener.addheaders.append( ( 'Cookie''email=' + "xxxxxxx@163.com" ) )
    req = urllib2.Request( "http://www.zhihu.com/" )
    response = opener.open(req)
    print response.headers
    retdata = response.read()

    1.4 Timeout设置超时

    在Python2.6之前的版本,urllib2的API并没有暴露Timeout的设置,要设置Timeout值,只能更改Socket的全局Timeout值。示例如下:

    import urllib2
    import socket
    socket.setdefaulttimeout(10# 10 秒钟后超时
    urllib2.socket.setdefaulttimeout(10# 另一种方式

    在Python2.6及新的版本中,urlopen函数提供了对Timeout的设置,示例如下:

    import urllib2
    request=urllib2.Request('http://www.zhihu.com')
    response = urllib2.urlopen(request,timeout=2)
    html=response.read()
    print html

    1.5 获取HTTP响应码

    对于200 OK来说,只要使用urlopen返回的response对象的getcode()方法就可以得到HTTP的返回码。但对其他返回码来说,urlopen会抛出异常。这时候,就要检查异常对象的code属性了,示例如下:

    import urllib2
    try:
        response = urllib2.urlopen('http://www.google.com')
        print response
    except urllib2.HTTPError as e:
        if hasattr(e, 'code'):
            print 'Error code:',e.code

    1.6 重定向

    urllib2默认情况下会针对HTTP 3XX返回码自动进行重定向动作。要检测是否发生了重定向动作,只要检查一下Response的URL和Request的URL是否一致就可以了,示例如下:

    import urllib2
    response = urllib2.urlopen('http://www.zhihu.cn')
    isRedirected = response.geturl() == 'http://www.zhihu.cn'

    如果不想自动重定向,可以自定义HTTPRedirectHandler类,示例如下:

    import urllib2
    class RedirectHandler(urllib2.HTTPRedirectHandler):
        def http_error_301(self, req, fp, code, msg, headers):
            pass
        def http_error_302(self, req, fp, code, msg, headers):
            result = urllib2.HTTPRedirectHandler.http_error_301(self, req, fp, code, 
            msg, headers)
            result.status = code
            result.newurl = result.geturl()
            return result
    opener = urllib2.build_opener(RedirectHandler)
    opener.open('http://www.zhihu.cn')

    1.7 Proxy的设置

    在做爬虫开发中,必不可少地会用到代理。urllib2默认会使用环境变量http_proxy来设置HTTP Proxy。但是我们一般不采用这种方式,而是使用ProxyHandler在程序中动态设置代理,示例代码如下:

    import urllib2
    proxy = urllib2.ProxyHandler({'http''127.0.0.1:8087'})
    opener = urllib2.build_opener([proxy,])
    urllib2.install_opener(opener)
    response = urllib2.urlopen('http://www.zhihu.com/')
    print response.read()

    这里要注意的一个细节,使用urllib2.install_opener()会设置urllib2的全局opener,之后所有的HTTP访问都会使用这个代理。这样使用会很方便,但不能做更细粒度的控制,比如想在程序中使用两个不同的Proxy设置,这种场景在爬虫中很常见。比较好的做法是不使用install_opener去更改全局的设置,而只是直接调用opener的open方法代替全局的urlopen方法,修改如下:

    import urllib2
    proxy = urllib2.ProxyHandler({'http''127.0.0.1:8087'})
    opener = urllib2.build_opener(proxy,)
    response = opener.open("http://www.zhihu.com/")
    print response.read()


    2. httplib/urllib实现

    httplib模块是一个底层基础模块,可以看到建立HTTP请求的每一步,但是实现的功能比较少,正常情况下比较少用到。在Python爬虫开发中基本上用不到,所以在此只是进行一下知识普及。下面介绍一下常用的对象和函数:


    • 创建HTTPConnection对象:

      class httplib.HTTPConnection(host[, port[, strict[, timeout[, source_address]]]])。

    • 发送请求:

      HTTPConnection.request(method, url[, body[, headers]])。

    • 获得响应:

      HTTPConnection.getresponse()。

    • 读取响应信息:

      HTTPResponse.read([amt])。

    • 获得指定头信息:

      HTTPResponse.getheader(name[, default])。

    • 获得响应头(header, value)元组的列表:

      HTTPResponse.getheaders()。

    • 获得底层socket文件描述符:

      HTTPResponse.fileno()。

    • 获得头内容:

      HTTPResponse.msg。

    • 获得头http版本:

      HTTPResponse.version。

    • 获得返回状态码:

      HTTPResponse.status。

    • 获得返回说明:

      HTTPResponse.reason。

    接下来演示一下GET请求和POST请求的发送,首先是GET请求的示例,如下所示:

    import httplib
    conn =None
    try:
        conn = httplib.HTTPConnection("www.zhihu.com")
        conn.request("GET""/")
        response = conn.getresponse()
        print response.status, response.reason
        print '-' * 40
        headers = response.getheaders()
        for h in headers:
            print h
        print '-' * 40
        print response.msg
    except Exception,e:
        print e
    finally:
        if conn:
            conn.close()

    POST请求的示例如下:

    import httplib, urllib
    conn = None
    try:
        params = urllib.urlencode({'name''qiye''age'22})
        headers = {"Content-type""application/x-www-form-urlencoded"
        , "Accept""text/plain"}
        conn = httplib.HTTPConnection("www.zhihu.com"80, timeout=3)
        conn.request("POST""/login", params, headers)
        response = conn.getresponse()
        print response.getheaders() # 获取头信息
        print response.status
        print response.read()
    except Exception, e:
        print e
        finally:
        if conn:
            conn.close()

    3. 更人性化的Requests

    Python中Requests实现HTTP请求的方式,是本人极力推荐的,也是在Python爬虫开发中最为常用的方式。Requests实现HTTP请求非常简单,操作更加人性化。

    Requests库是第三方模块,需要额外进行安装。Requests是一个开源库,源码位于:

    GitHub: https://github.com/kennethreitz/requests

    希望大家多多支持作者。

    使用Requests库需要先进行安装,一般有两种安装方式:

    • 使用pip进行安装,安装命令为:pip install requests,不过可能不是最新版。

    • 直接到GitHub上下载Requests的源代码,下载链接为:

      https://github.com/kennethreitz/requests/releases

      将源代码压缩包进行解压,然后进入解压后的文件夹,运行setup.py文件即可。

    如何验证Requests模块安装是否成功呢?在Python的shell中输入import requests,如果不报错,则是安装成功。如图3-5所示。

    640?wx_fmt=png

    ▲图3-5 验证Requests安装

    3.1 首先还是实现一个完整的请求与响应模型

    以GET请求为例,最简单的形式如下:

    import requests
    r = requests.get('http://www.baidu.com')
    print r.content

    大家可以看到比urllib2实现方式的代码量少。接下来演示一下POST请求,同样是非常简短,更加具有Python风格。示例如下:

    import requests
    postdata={'key':'value'}
    r = requests.post('http://www.xxxxxx.com/login',data=postdata)
    print r.content

    HTTP中的其他请求方式也可以用Requests来实现,示例如下:

    r = requests.put('http://www.xxxxxx.com/put', data = {'key':'value'})
    r = requests.delete('http://www.xxxxxx.com/delete')
    r = requests.head('http://www.xxxxxx.com/get')
    r = requests.options('http://www.xxxxxx.com/get')

    接着讲解一下稍微复杂的方式,大家肯定见过类似这样的URL:

    http://zzk.cnblogs.com/s/blogpost?Keywords=blog:qiyeboy&pageindex=1

    就是在网址后面紧跟着“?”,“?”后面还有参数。那么这样的GET请求该如何发送呢?肯定有人会说,直接将完整的URL带入即可,不过Requests还提供了其他方式,示例如下:

    import requests
        payload = {'Keywords''blog:qiyeboy','pageindex':1}
    r = requests.get('http://zzk.cnblogs.com/s/blogpost', params=payload)
    print r.url

    通过打印结果,我们看到最终的URL变成了:

    http://zzk.cnblogs.com/s/blogpost?Keywords=blog:qiyeboy&pageindex=1

    3.2 响应与编码

    还是从代码入手,示例如下:

    import requests
    r = requests.get('http://www.baidu.com')
    print 'content-->'+r.content
    print 'text-->'+r.text
    print 'encoding-->'+r.encoding
    r.encoding='utf-8'
    print 'new text-->'+r.text

    其中r.content返回的是字节形式,r.text返回的是文本形式,r.encoding返回的是根据HTTP头猜测的网页编码格式。

    输出结果中:“text-->”之后的内容在控制台看到的是乱码,“encoding-->”之后的内容是ISO-8859-1(实际上的编码格式是UTF-8),由于Requests猜测编码错误,导致解析文本出现了乱码。Requests提供了解决方案,可以自行设置编码格式,r.encoding='utf-8'设置成UTF-8之后,“new text-->”的内容就不会出现乱码。

    但是这种手动的方式略显笨拙,下面提供一种更加简便的方式:chardet,这是一个非常优秀的字符串/文件编码检测模块。安装方式如下:

    pip install chardet

    安装完成后,使用chardet.detect()返回字典,其中confidence是检测精确度,encoding是编码形式。示例如下:

    import requests
    r = requests.get('http://www.baidu.com')
    print chardet.detect(r.content)
    r.encoding = chardet.detect(r.content)['encoding']
    print r.text

    直接将chardet探测到的编码,赋给r.encoding实现解码,r.text输出就不会有乱码了。

    除了上面那种直接获取全部响应的方式,还有一种流模式,示例如下:

    import requests
    r = requests.get('http://www.baidu.com',stream=True)
    print r.raw.read(10)

    设置stream=True标志位,使响应以字节流方式进行读取,r.raw.read函数指定读取的字节数。

    3.3 请求头headers处理

    Requests对headers的处理和urllib2非常相似,在Requests的get函数中添加headers参数即可。示例如下:

    import requests
    user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
    headers={'User-Agent':user_agent}
    r = requests.get('http://www.baidu.com',headers=headers)
    print r.content

    3.4 响应码code和响应头headers处理

    获取响应码是使用Requests中的status_code字段,获取响应头使用Requests中的headers字段。示例如下:

    import requests
    r = requests.get('http://www.baidu.com')
    if r.status_code == requests.codes.ok:
        print r.status_code# 响应码
        print r.headers# 响应头
        print r.headers.get('content-type')# 推荐使用这种获取方式,获取其中的某个字段
        print r.headers['content-type']# 不推荐使用这种获取方式
    else:
        r.raise_for_status()

    上述程序中,r.headers包含所有的响应头信息,可以通过get函数获取其中的某一个字段,也可以通过字典引用的方式获取字典值,但是不推荐,因为如果字段中没有这个字段,第二种方式会抛出异常,第一种方式会返回None。

    r.raise_for_status()是用来主动地产生一个异常,当响应码是4XX或5XX时,raise_for_status()函数会抛出异常,而响应码为200时,raise_for_status()函数返回None。

    3.5 Cookie处理

    如果响应中包含Cookie的值,可以如下方式获取Cookie字段的值,示例如下:

    import requests
    user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
    headers={'User-Agent':user_agent}
    r = requests.get('http://www.baidu.com',headers=headers)
    # 遍历出所有的cookie字段的值
    for cookie in r.cookies.keys():
        print cookie+':'+r.cookies.get(cookie)

    如果想自定义Cookie值发送出去,可以使用以下方式,示例如下:

    import requests
    user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
    headers={'User-Agent':user_agent}
    cookies = dict(name='qiye',age='10')
    r = requests.get('http://www.baidu.com',headers=headers,cookies=cookies)
    print r.text

    还有一种更加高级,且能自动处理Cookie的方式,有时候我们不需要关心Cookie值是多少,只是希望每次访问的时候,程序自动把Cookie的值带上,像浏览器一样。Requests提供了一个session的概念,在连续访问网页,处理登录跳转时特别方便,不需要关注具体细节。使用方法示例如下:

    import Requests
    oginUrl = 'http://www.xxxxxxx.com/login'
    s = requests.Session()
    #首先访问登录界面,作为游客,服务器会先分配一个cookie
    r = s.get(loginUrl,allow_redirects=True)
    datas={'name':'qiye','passwd':'qiye'}
    #向登录链接发送post请求,验证成功,游客权限转为会员权限
    r = s.post(loginUrl, data=datas,allow_redirects= True)
    print r.text

    上面的这段程序,其实是正式做Python开发中遇到的问题,如果没有第一步访问登录的页面,而是直接向登录链接发送Post请求,系统会把你当做非法用户,因为访问登录界面时会分配一个Cookie,需要将这个Cookie在发送Post请求时带上,这种使用Session函数处理Cookie的方式之后会很常用。

    3.6 重定向与历史信息

    处理重定向只是需要设置一下allow_redirects字段即可,例如:

    r=requests.get('http://www.baidu.com',allow_redirects=True)

    将allow_redirects设置为True,则是允许重定向;设置为False,则是禁止重定向。如果是允许重定向,可以通过r.history字段查看历史信息,即访问成功之前的所有请求跳转信息。示例如下:

    import requests
    r = requests.get('http://github.com')
    print r.url
    print r.status_code
    print r.history

    打印结果如下:

    https://github.com/
    200
    (<Response [301]>,)

    上面的示例代码显示的效果是访问GitHub网址时,会将所有的HTTP请求全部重定向为HTTPS。

    3.7 超时设置

    超时选项是通过参数timeout来进行设置的,示例如下:

    requests.get('http://github.com', timeout=2)

    3.8 代理设置

    使用代理Proxy,你可以为任意请求方法通过设置proxies参数来配置单个请求:

    import requests
    proxies = {
        "http""http://0.10.1.10:3128",
        "https""http://10.10.1.10:1080",
    }
    requests.get("http://example.org", proxies=proxies)

    也可以通过环境变量HTTP_PROXY和HTTPS_PROXY?来配置代理,但是在爬虫开发中不常用。你的代理需要使用HTTP Basic Auth,可以使用http://user:password@host/语法:

    proxies = {
        "http""http://user:pass@10.10.1.10:3128/",
    }


    03

    小结


    本文主要讲解了网络爬虫的结构和应用,以及Python实现HTTP请求的几种方法。希望大家对本文中的网络爬虫工作流程和Requests实现HTTP请求的方式重点吸收消化。

    本文摘编自《Python爬虫开发与项目实战》,经出版方授权发布。

    关于作者:范传辉,资深网虫,Python开发者,参与开发了多项网络应用,在实际开发中积累了丰富的实战经验,并善于总结,贡献了多篇技术文章广受好评。研究兴趣是网络安全、爬虫技术、数据分析、驱动开发等技术。

    640?wx_fmt=jpeg

    Python爬虫开发与项目实战

    扫码购买

    640?wx_fmt=png


    本书特色:

    • 由浅入深,从Python和Web前端基础开始讲起,逐步加深难度,层层递进。

    • 内容详实,从静态网站到动态网站,从单机爬虫到分布式爬虫,既包含基础知识点,又讲解了关键问题和难点分析,方便读者完成进阶。

    • 实用性强,本书共有9个爬虫项目,以系统的实战项目为驱动,由浅及深地讲解爬虫开发中所需的知识和技能。

    • 难点详析,对js加密的分析、反爬虫措施的突破、去重方案的设计、分布式爬虫的开发进行了细致的讲解。

    扫码购买

    640?wx_fmt=png

    展开全文
  • 150讲轻松搞定Python网络爬虫

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

    万次阅读 多人点赞 2019-09-21 00:02:43
    Python是什么 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言。 创始人Guido van Rossum是BBC出品英剧Monty Python’s Flying Circus(中文:蒙提·派森的...

    Python是什么

    Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言。

    创始人Guido van Rossum是BBC出品英剧Monty Python’s Flying Circus(中文:蒙提·派森的飞行马戏团)的狂热粉丝,因而将自己创造的这门编程语言命名为Python。

    人生苦短,我用python,翻译自"Life is short, you need Python"

    Python英式发音:/ˈpaɪθən/ ,中文类似‘拍森’。而美式发音:/ˈpaɪθɑːn/,中文类似‘拍赏’。我看麻省理工授课教授读的是‘拍赏’,我觉得国内大多是读‘拍森’吧。

    2017年python排第一也无可争议,比较AI第一语言,在当下人工智能大数据大火的情况下,python无愧第一语言的称号,至于C、C++、java都是万年的老大哥了,在代码量比较方面,小编相信java肯定是完爆其它语言的。

    不过从这一年的编程语言流行趋势看,java依然是传播最多的,比较无论app、web、云计算都离不开,而其相对python而言,学习路径更困难一点,想要转行编程,而且追赶潮流,python已然是最佳语言。

    许多大型网站就是用Python开发的,国内:豆瓣、搜狐、金山、腾讯、盛大、网易、百度、阿里、淘宝、热酷、土豆、新浪、果壳…; 国外:谷歌、NASA、YouTube、Facebook、工业光魔、红帽…

    Python将被纳入高考内容

    浙江省信息技术课程改革方案已经出台,Python确定进入浙江省信息技术高考,从2018年起浙江省信息技术教材编程语言将会从vb更换为Python。其实不止浙江,教育大省北京和山东也确定要把Python编程基础纳入信息技术课程和高考的内容体系,Python语言课程化也将成为孩子学习的一种趋势。尤其山东省最新出版的小学信息技术六年级教材也加入了Python内容,小学生都开始接触Python语言了!!

    再不学习,又要被小学生完爆了。。。

     

    Python入门教程

    Python能做什么

    • 网络爬虫
    • Web应用开发
    • 系统网络运维
    • 科学与数字计算
    • 图形界面开发
    • 网络编程
    • 自然语言处理(NLP)
    • 人工智能
    • 区块链
    • 多不胜举。。。

    Python入门爬虫

    这是我的第一个python项目,在这里与大家分享出来~

    • 需求
      • 我们目前正在开发一款产品其功能大致是:用户收到短信如:购买了电影票或者火车票机票之类的事件。然后app读取短信,解析短信,获取时间地点,然后后台自动建立一个备忘录,在事件开始前1小时提醒用户。
    • 设计
      • 开始我们将解析的功能放在了服务端,但是后来考虑到用户隐私问题。后来将解析功能放到了app端,服务端只负责收集数据,然后将新数据发送给app端。
      • 关于服务端主要是分离出两个功能,一、响应app端请求返回数据。二、爬取数据,存入数据库。
      • 响应请求返回数据使用java来做,而爬取数据存入数据库使用python来做,这样分别使用不同语言来做是因为这两种语言各有优势,java效率比python高些,适合做web端,而爬取数据并不是太追求性能且python语言和大量的库适合做爬虫。
    • 代码
      • 本项目使用python3的版本
      • 获取源码:扫描下方关注微信公众号「裸睡的猪」回复:爬虫入门 获取
         

         

      • 了解这个项目你只需要有简单的python基础,能了解python语法就可以。其实我自己也是python没学完,然后就开始写,遇到问题就百度,边做边学这样才不至于很枯燥,因为python可以做一些很有意思的事情,比如模拟连续登录挣积分,比如我最近在写一个预定模范出行车子的python脚本。推荐看廖雪峰的python入门教程
      • 首先带大家看看我的目录结构,开始我打算是定义一个非常好非常全的规范,后来才发现由于自己不熟悉框架,而是刚入门级别,所以就放弃了。从简而入:
      • 下面咱们按照上图中的顺序,从上往下一个一个文件的讲解init.py包的标识文件,python包就是文件夹,当改文件夹下有一个init.py文件后它就成为一个package,我在这个包中引入一些py供其他py调用。

    init.py

    # -*- coding: UTF-8 -*-  
    
    # import need manager module  
    import MongoUtil  
    import FileUtil  
    import conf_dev  
    import conf_test  
    import scratch_airport_name  
    import scratch_flight_number  
    import scratch_movie_name  
    import scratch_train_number  
    import scratch_train_station  
    import MainUtil
    

    下面两个是配置文件,第一个是开发环境的(windows),第二个是测试环境的(linux),然后再根据不同系统启用不同的配置文件

    conf_dev.py

    # -*- coding: UTF-8 -*-  
    # the configuration file of develop environment  
    
    # path configure  
    data_root_path = 'E:/APK98_GNBJ_SMARTSERVER/Proj-gionee-data/smart/data'  
    
    # mongodb configure  
    user = "cmc"  
    pwd = "123456"  
    server = "localhost"  
    port = "27017"  
    db_name = "smartdb"
    

    conf_test.py

    # -*- coding: UTF-8 -*-  
    # the configuration file of test environment  
    
    #path configure  
    data_root_path = '/data/app/smart/data'  
    
    #mongodb configure  
    user = "smart"  
    pwd = "123456"  
    server = "10.8.0.30"  
    port = "27017"  
    db_name = "smartdb"
    

    下面文件是一个util文件,主要是读取原文件的内容,还有将新内容写入原文件。

    FileUtil.py

    # -*- coding: UTF-8 -*-  
    import conf_dev  
    import conf_test  
    import platform  
    
    
    # configure Multi-confronment  
    # 判断当前系统,并引入相对的配置文件
    platform_os = platform.system()  
    config = conf_dev  
    if (platform_os == 'Linux'):  
        config = conf_test  
    # path  
    data_root_path = config.data_root_path  
    
    
    # load old data  
    def read(resources_file_path, encode='utf-8'):  
        file_path = data_root_path + resources_file_path  
        outputs = []  
        for line in open(file_path, encoding=encode):  
            if not line.startswith("//"):  
                outputs.append(line.strip('\n').split(',')[-1])  
        return outputs  
    
    
    # append new data to file from scratch  
    def append(resources_file_path, data, encode='utf-8'):  
        file_path = data_root_path + resources_file_path  
        with open(file_path, 'a', encoding=encode) as f:  
            f.write(data)  
        f.close
    

    下面这个main方法控制着执行流程,其他的执行方法调用这个main方法

    MainUtil.py

    # -*- coding: UTF-8 -*-  
    
    import sys  
    from datetime import datetime  
    import MongoUtil  
    import FileUtil  
    
    # @param resources_file_path 资源文件的path  
    # @param base_url 爬取的连接  
    # @param scratch_func 爬取的方法  
    def main(resources_file_path, base_url, scratch_func):  
        old_data = FileUtil.read(resources_file_path)   #读取原资源  
        new_data = scratch_func(base_url, old_data)     #爬取新资源  
        if new_data:        #如果新数据不为空  
            date_new_data = "//" + datetime.now().strftime('%Y-%m-%d') + "\n" + "\n".join(new_data) + "\n"      #在新数据前面加上当前日期  
            FileUtil.append(resources_file_path, date_new_data)     #将新数据追加到文件中  
            MongoUtil.insert(resources_file_path, date_new_data)    #将新数据插入到mongodb数据库中  
        else:   #如果新数据为空,则打印日志  
            print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), '----', getattr(scratch_func, '__name__'), ": nothing to update ")
    

    将更新的内容插入mongodb中

    MongoUtil.py

    # -*- coding: UTF-8 -*-  
    
    import platform  
    from pymongo import MongoClient  
    from datetime import datetime, timedelta, timezone  
    import conf_dev  
    import conf_test  
    
    # configure Multi-confronment  
    platform_os = platform.system()  
    config = conf_dev  
    if (platform_os == 'Linux'):  
        config = conf_test  
    # mongodb  
    uri = 'mongodb://' + config.user + ':' + config.pwd + '@' + config.server + ':' + config.port + '/' + config.db_name  
    
    
    # 将数据写入mongodb  
    # @author chenmc  
    # @param uri connect to mongodb  
    # @path save mongodb field  
    # @data save mongodb field  
    # @operation save mongodb field default value 'append'  
    # @date 2017/12/07 16:30  
    # 先在mongodb中插入一条自增数据 db.sequence.insert({ "_id" : "version","seq" : 1})  
    
    def insert(path, data, operation='append'):  
        client = MongoClient(uri)  
        resources = client.smartdb.resources  
        sequence = client.smartdb.sequence  
        seq = sequence.find_one({"_id": "version"})["seq"]      #获取自增id  
        sequence.update_one({"_id": "version"}, {"$inc": {"seq": 1}})       #自增id+1  
        post_data = {"_class": "com.gionee.smart.domain.entity.Resources", "version": seq, "path": path,  
                     "content": data, "status": "enable", "operation": operation,  
                     "createtime": datetime.now(timezone(timedelta(hours=8)))}  
        resources.insert(post_data)     #插入数据
    

    项目引入的第三方库,可使用pip install -r requirements.txt下载第三方库

    requirements.txt

    # need to install module# need to install module  
    bs4  
    pymongo  
    requests  
    json
    

    下面真正的执行方法来了,这五个py分别表示爬取五种信息:机场名、航班号、电影名、列车号、列车站。他们的结构都差不多,如下:

    第一部分:定义查找的url;
    第二部分:获取并与旧数据比较,返回新数据;
    第三部分:main方法,执行写入新数据到文件和mongodb中;
    

    scratch_airport_name.py:爬取全国机场

    # -*- coding: UTF-8 -*-  
    import requests  
    import bs4  
    import json  
    import MainUtil  
    
    resources_file_path = '/resources/airplane/airportNameList.ini'  
    scratch_url_old = 'https://data.variflight.com/profiles/profilesapi/search'  
    scratch_url = 'https://data.variflight.com/analytics/codeapi/initialList'  
    get_city_url = 'https://data.variflight.com/profiles/Airports/%s'  
    
    
    #传入查找网页的url和旧数据,然后本方法会比对原数据中是否有新的条目,如果有则不加入,如果没有则重新加入,最后返回新数据
    def scratch_airport_name(scratch_url, old_airports):  
        new_airports = []  
        data = requests.get(scratch_url).text  
        all_airport_json = json.loads(data)['data']  
        for airport_by_word in all_airport_json.values():  
            for airport in airport_by_word:  
                if airport['fn'] not in old_airports:  
                    get_city_uri = get_city_url % airport['id']  
                    data2 = requests.get(get_city_uri).text  
                    soup = bs4.BeautifulSoup(data2, "html.parser")  
                    city = soup.find('span', text="城市").next_sibling.text  
                    new_airports.append(city + ',' + airport['fn'])  
        return new_airports  
    
     #main方法,执行这个py,默认调用main方法,相当于java的main
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_airport_name)
    

    scratch_flight_number.py:爬取全国航班号

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    
    import requests  
    import bs4  
    import MainUtil  
    
    resources_file_path = '/resources/airplane/flightNameList.ini'  
    scratch_url = 'http://www.variflight.com/sitemap.html?AE71649A58c77='  
    
    
    def scratch_flight_number(scratch_url, old_flights):  
        new_flights = []  
        data = requests.get(scratch_url).text  
        soup = bs4.BeautifulSoup(data, "html.parser")  
        a_flights = soup.find('div', class_='list').find_all('a', recursive=False)  
        for flight in a_flights:  
            if flight.text not in old_flights and flight.text != '国内航段列表':  
                new_flights.append(flight.text)  
        return new_flights  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_flight_number)
    

    scratch_movie_name.py:爬取最近上映的电影

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    import re  
    import requests  
    import bs4  
    import json  
    import MainUtil  
    
    # 相对路径,也是需要将此路径存入数据库  
    resources_file_path = '/resources/movie/cinemaNameList.ini'  
    scratch_url = 'http://theater.mtime.com/China_Beijing/'  
    
    
    # scratch data with define url  
    def scratch_latest_movies(scratch_url, old_movies):  
        data = requests.get(scratch_url).text  
        soup = bs4.BeautifulSoup(data, "html.parser")  
        new_movies = []  
        new_movies_json = json.loads(  
            soup.find('script', text=re.compile("var hotplaySvList")).text.split("=")[1].replace(";", ""))  
        coming_movies_data = soup.find_all('li', class_='i_wantmovie')  
        # 上映的电影  
        for movie in new_movies_json:  
            move_name = movie['Title']  
            if move_name not in old_movies:  
                new_movies.append(movie['Title'])  
        # 即将上映的电影  
        for coming_movie in coming_movies_data:  
            coming_movie_name = coming_movie.h3.a.text  
            if coming_movie_name not in old_movies and coming_movie_name not in new_movies:  
                new_movies.append(coming_movie_name)  
        return new_movies  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_latest_movies)
    

    scratch_train_number.py:爬取全国列车号

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    import requests  
    import bs4  
    import json  
    import MainUtil  
    
    resources_file_path = '/resources/train/trainNameList.ini'  
    scratch_url = 'http://www.59178.com/checi/'  
    
    
    def scratch_train_number(scratch_url, old_trains):  
        new_trains = []  
        resp = requests.get(scratch_url)  
        data = resp.text.encode(resp.encoding).decode('gb2312')  
        soup = bs4.BeautifulSoup(data, "html.parser")  
        a_trains = soup.find('table').find_all('a')  
        for train in a_trains:  
            if train.text not in old_trains and train.text:  
                new_trains.append(train.text)  
        return new_trains  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_train_number)
    

    scratch_train_station.py:爬取全国列车站

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    import requests  
    import bs4  
    import random  
    import MainUtil  
    
    resources_file_path = '/resources/train/trainStationNameList.ini'  
    scratch_url = 'http://www.smskb.com/train/'  
    
    
    def scratch_train_station(scratch_url, old_stations):  
        new_stations = []  
        provinces_eng = (  
            "Anhui", "Beijing", "Chongqing", "Fujian", "Gansu", "Guangdong", "Guangxi", "Guizhou", "Hainan", "Hebei",  
            "Heilongjiang", "Henan", "Hubei", "Hunan", "Jiangsu", "Jiangxi", "Jilin", "Liaoning", "Ningxia", "Qinghai",  
            "Shandong", "Shanghai", "Shanxi", "Shanxisheng", "Sichuan", "Tianjin", "Neimenggu", "Xianggang", "Xinjiang",  
            "Xizang",  
            "Yunnan", "Zhejiang")  
        provinces_chi = (  
            "安徽", "北京", "重庆", "福建", "甘肃", "广东", "广西", "贵州", "海南", "河北",  
            "黑龙江", "河南", "湖北", "湖南", "江苏", "江西", "吉林", "辽宁", "宁夏", "青海",  
            "山东", "上海", "陕西", "山西", "四川", "天津", "内蒙古", "香港", "新疆", "西藏",  
            "云南", "浙江")  
        for i in range(0, provinces_eng.__len__(), 1):  
            cur_url = scratch_url + provinces_eng[i] + ".htm"  
            resp = requests.get(cur_url)  
            data = resp.text.encode(resp.encoding).decode('gbk')  
            soup = bs4.BeautifulSoup(data, "html.parser")  
            a_stations = soup.find('left').find('table').find_all('a')  
            for station in a_stations:  
                if station.text not in old_stations:  
                    new_stations.append(provinces_chi[i] + ',' + station.text)  
        return new_stations  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_train_station)
    

    将项目放到测试服务器(centos7系统)中运行起来,我写了一个crontab,定时调用他们,下面贴出crontab。

    /etc/crontab

    SHELL=/bin/bash  
    PATH=/sbin:/bin:/usr/sbin:/usr/bin  
    MAILTO=root  
    
    # For details see man 4 crontabs  
    
    # Example of job definition:  
    # .---------------- minute (0 - 59)  
    # |  .------------- hour (0 - 23)  
    # |  |  .---------- day of month (1 - 31)  
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...  
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat  
    # |  |  |  |  |  
    # *  *  *  *  * user-name  command to be executed  
      0  0  *  *  * root python3 /data/app/smart/py/scratch_movie_name.py    >> /data/logs/smartpy/out.log 2>&1  
      0  1  *  *  1 root python3 /data/app/smart/py/scratch_train_station.py >> /data/logs/smartpy/out.log 2>&1  
      0  2  *  *  2 root python3 /data/app/smart/py/scratch_train_number.py  >> /data/logs/smartpy/out.log 2>&1  
      0  3  *  *  4 root python3 /data/app/smart/py/scratch_flight_number.py >> /data/logs/smartpy/out.log 2>&1  
      0  4  *  *  5 root python3 /data/app/smart/py/scratch_airport_name.py  >> /data/logs/smartpy/out.log 2>&1
    

    后续

    目前项目已经正常运行了三个多月啦。。。

    有问题反馈

    在阅读与学习中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流

    • 微信公众号:裸睡的猪
    • 在下面留言
    • 直接给我私信

    关于此公众号

    • 后期或提供各种软件的免费激活码
    • 推送python,java等编程技术文章和面试技巧
    • 当然你们可以将你们感兴趣的东西直接送给我
    • 谢谢你们真诚的关注,此公众号以后获得的收益将全部通过抽奖的形式送给大家
    • 以后如果博主要创业的话,也会在此公众号中挑选小伙伴哦~
    • 希望大家分享出去,让更多想学习python的朋友看到~

     

     

    展开全文
  • “来我公司写爬虫吗?会坐牢的那种!”

    万次阅读 多人点赞 2020-03-16 10:25:12
    欢迎关注“技术领导力”博客,每天早上8:30推送 ...张强,在一家大数据风控公司担任爬虫工程师,每当看到网上的段子,爬虫学得好,监狱进得早,他总是莞尔一笑,心想:关我毛事啊,我只是个程序员,要坐牢也是老板去...

     欢迎关注“技术领导力”博客,每天早上8:30推送

     

    “你交代一下,总共抓了多少数据,在哪些网站抓的,数据干什么用了?看看够在里面呆几年。。。”警察语气凝重地对张强说。

     

    程序员张强(化名),回忆起这两天来的经历,仍心有余悸。

     

    张强,在一家大数据风控公司担任爬虫工程师,每当看到网上的段子,爬虫学得好,监狱进得早,他总是莞尔一笑,心想:关我毛事啊,我只是个程序员,要坐牢也是老板去坐吧,我又没拿数据去卖钱。

     

    时间回到9月,某一天的上午,张强和同事们像往常一样上班,突然公司里来了一群警察,要求所有人双手离开电脑、手机等设备,全部靠墙站立,工程师小哥哥、小姐姐们哪里见过这个架势,都懵了,只得照办。

     

    警察查封了公司,带走了公司所有人,于是有了前面的问话。

     

     

    01

    我只是个写爬虫的,跟我有什么关系?

     

    许多程序员都有这样的想法,技术是无罪的,我只是个打工的程序员,公司干违法的业务,跟我没关系。。。只能说,程序猿们真是图羊图森破了。

     

    我们先来看几个真实的法院判决案例:

    案例一:数据拥有者有证据能够举证你的数据是抓取来的。如下,今日头条对起诉上海晟品法院宣判结果。

    640?wx_fmt=jpeg

    (图片文字来自中国判决文书网)

    从文书描述来看,修改UA、修改device id、绕开网站访问频率控制这是写爬虫的基本,这些技术手法反而成了获罪的依据。

    案例二:抓取用户社交数据,尤其是用户隐私相关。

    640?wx_fmt=jpeg

    (图片文字来自新浪网)

    案例三:用爬虫技术扰乱对方网站经营规则,且牟利。比如这个:

    640?wx_fmt=jpeg

    640?wx_fmt=jpeg

    (图片文字来自中国永嘉公号)

    图上描述做搜索引擎排名的技术,其实就是利用爬虫技术规模化的访问网页。

    在我们通常的认知里,因为互联网推崇分享精神,所以认为只要是网络公开数据就可以抓取,但是通过上面的案例来看,有几个禁忌,抓取的数据最好不要直接商用,涉及社交信息/用户信息要谨慎。

    老板交代你抓取敏感任务时,让老板先看下刑法第285条。公司从事违法业务,不代表个人行为就没事,只是还没入有关部门的法眼。

     

    02

    9月成为大数据风控行业的“黑暗月”

     

    同盾科技爬虫部门已解散。据报道,同盾科技爬虫部门已解散,员工集体待岗,并被建议不要离开杭州,否则有被抓风险;由于局面失控,蒋韬已出国避风头。知情人士透露,魔蝎科技与新颜科技近期被查系同盾科技举报。之所以举报魔蝎科技,意在打击其背后的邦盛科技,后者是同盾科技的竞争对手。

     

    紧接着,同盾科技发布“辟谣声明”,称蒋韬一直在国内照常处理公司事务;信川科技于2018年开始逐步调整业务,目前已停止全部相关业务,员工调至其他岗位;举报传言是无中生有,恶意中伤。

     

    巧达科技被查封,全体员工被警方带走。有消息称招聘数据公司巧达科技被查封,全体员工被警方带走。一位巧达科技前员工告诉笔者,“(最近)陆续有HR等非核心员工回家,但核心高管依然失联中。”多位业内人士和律师认为,巧达科技出事可能与其未经授权获取和使用简历、“贩卖”简历信息等涉嫌侵犯用户隐私权、侵犯公民个人信息的行为有关。

     

    公开资料显示,巧达科技成立于2014年7月,号称拥有中国最大的简历数据库,巧达科技数据库有2.2亿自然人的简历、简历累计总数37亿份。此外,巧达科技还有超过10亿份通讯录,也就是说,它掌握了超过57%的中国人的信息。

     

    这些获取渠道并不正规的数据为巧达科技带来了过亿的收入。2016年,巧达科技全年收入1.2亿元,净利润4800万元;2017年,巧达科技全年收入4.11亿元,净利润1.86亿元,净利润率超过45%。

     

    魔蝎科技负责人及员工被抓捕,涉案人员120余名。9月6日,网友TonyStark爆料称,杭州西湖分局集结200余名警力,对涉嫌侵犯公民个人信息的魔蝎科技进行统一抓捕。截止目前抓获涉案人员120余名,冻结资金2300余万元,勘验固定服务器1000余台,扣押电脑100多台,手机200余部。案件正在进一步侦办中。

    640?wx_fmt=png

    随后,杭州市公安局西湖区分局向媒体证实,魔蝎科技的相关人员已经被经侦大队带走调查。

    03

    信号明显:“灰色”地带的监管力度在加强!

     

    有业内人士分析表示,爬虫并不犯法,而是爬出后的信息如何使用,存在隐私侵权、数据滥用等风险,特别是在数据的授权、来源、用途十分不透明的情况下。

     

    西南财经大学普惠金融与智能金融研究中心副主任陈文表示:“风控数据公司因为拥有用户的信息、关系图,在获客、营销、催收阶段都能助力现金贷机构。但数据来源大多处于灰色地域,对于个人隐私缺乏保护,存在广泛的数据滥用问题。”

     

    针对这些问题,监管也在路上。今年5月28日,国家互联网信息办公室就《数据安全管理办法(征求意见稿)》(以下简称《办法》)公开征求意见。对于网络运营者超出运营需要收集个人信息的行为,《办法》作出了限制性规定,对“网络产品核心业务功能运行的个人信息”以外的信息,网络运营者不得因个人信息主体未同意收集而拒绝提供核心业务功能服务。

     

    针对网络爬虫等抓取网页的自动化手段,《办法》明确应不妨碍网站正常运行,并列明具体的访问收集流量不得超过网站日均流量的1/3。对数据泄露才确定网络安全负责人的问题,其明确数据安全责任人的任职要求,突出网络运营者主要负责人、数据安全责任人的姓名及联系方式等。

     

     

     

    04

    使用爬虫技术的公司,触犯了什么法律?

     

    对爬虫技术应用不当的企业,可能涉及的罪名有三个:

     

    一、侵犯公民个人信息罪

     

    1.爬取的数据信息属于公民个人信息范畴

    公民个人信息,是指以电子或者其他方式记录的,能够单独或者与其他信息结合识别特定自然人身份,或者反映特定自然人活动情况的各种信息,包括姓名、身份证件号码、通信通讯联系方式、住址、账号密码、财产状况、行踪轨迹等。

     

    2.利用爬虫技术获取的公民个人信息为非法获取的

    利用爬虫技术收集公民个人信息数据,应当获得被收集人的同意,尤其是在数据中包含身份证号、信用信息等敏感数据的情况下,还需要获得明示同意。同时,利用网络漏洞非法下载、非法购买等行为,都属于“非法获取”公民个人信息。

     

    3.相关法律依据:《刑法》第253条

    【侵犯公民个人信息罪】违反国家有关规定,向他人出售或者提供公民个人信息,情节严重的,处三年以下有期徒刑或者拘役,并处或者单处罚金;情节特别严重的,处三年以上七年以下有期徒刑,并处罚金。

     

    单位犯前三款罪的,对单位判处罚金,并对其直接负责的主管人员和其他直接责任人员,依照该款的规定处罚

    敲黑板划重点,上面标红加粗的就是写爬虫程序员也在坐牢的法律依据。

     

    二、构成非法获取计算机信息系统数据罪

     

    1.利用爬虫技术侵入计算机信息系统获取数据,或采用其他技术手段获取计算机信息系统数据

    任何组织或个人不得危害计算机信息系统安全;不得破坏计算机及其相关的配套的设备、设施(含网络)安全,破坏其运行环境安全、信息安全,影响其功能正常发挥。

    因此企业若在爬取数据时,存在危害计算机信息系统安全的行为,包括破解被爬企业的防抓取措施、加密算法、技术保护措施等,则很有可能被认定为“侵入或以其他技术手段获取计算机信息系统数据”。

     

    2. 相关法律依据:《刑法》第285条

    【非法侵入计算机信息系统罪】违反国家规定,侵入国家事务、国防建设、尖端科学技术领域的计算机信息系统的,处三年以下有期徒刑或者拘役。

     

    【提供侵入、非法控制计算机信息系统程序、工具罪】提供专门用于侵入、非法控制计算机信息系统的程序、工具,或者明知他人实施侵入、非法控制计算机信息系统的违法犯罪行为,而为其提供程序、工具,情节严重的,依照前款的规定处罚。

     

    单位犯前三款罪的,对单位判处罚金,并对其直接负责的主管人员和其他直接责任人员,依照该款的规定处罚。

     

    看到了吧!别以为写了个NB的爬虫破解程序丢到GitHub上,就没事。如果被人用来从事非法勾当,你也是要坐牢滴。

     

    三、非法侵入计算机信息系统罪

     

    1.提供数据信息的网站为国家事务、国防建设、尖端科学技术领域的计算机信息系统;

     

    高频使用的网站,如“国家企业信用信息公示系统”“中国裁判文书网”“中国执行信息公开网”以及各地政府网站等,都属于“国家事务”网站的法律范畴内。

     

    2.对计算机信息系统具有侵入行为

    (1)只要有侵入行为,而不论侵入行为的结果。

    (2)一般法院在认定上主要有两种方式:1)以非法手段登录网站,获取原本不该有权限获取的数据信息;2)将恶意程序、非法文件等发送至网站,对网站的正常运行产生影响。

    (3)在爬取此类网站的公开数据时,不存在“侵入”计算机信息系统的情形。但当批量爬取数据信息时,需特别关注是否会对网站的正常运行产生影响,切不可逾越红线。

     

    各位程序员兄弟姐妹们,仔细读完以上内容,判断下所在公司的合法性,该做准备的要趁早准备,不要抱有侥幸之心,更不要觉得老板“后台”硬没事,真要出事了你可能就是主犯,老板却逍遥自在。

     

     

    05

    爬虫程序员如何避免牢狱之灾?

     

    一、侵犯公民个人信息罪,合规建议:

    利用爬虫技术获取公民个人信息的,应该严格遵守相关法律、行政法规、部门规章的规定,否则极易落入“非法获取”公民个人信息的法律风险范畴。

     

    此外,关于在公民个人信息已合法公开的情况下,利用爬虫技术对其进行抓取是否构成非法获取这一问题,暂时没有明确答案,但《民法典人格权编》第816条写到:行为人收集、处理自然人自行公开的或者其他已经合法公开的信息不承担民事责任,但是该自然人明确拒绝或者处理该信息侵害其重大利益的除外。

     

    可以明确的是,收集已合法公开的个人信息应不属于违法,但在立法尚不完善的阶段,仍建议谨慎使用爬虫技术抓取公开的个人信息。

     

    二、非法获取计算机信息系统数据罪,合规建议:

    严格禁止通过技术手段绕过服务器的访问限制,或破解被爬网站为保护数据而采取的加密算法及技术保护措施,从而对被爬网站受保护的计算机信息系统中的数据进行爬取。

     

    若被爬网站设定了获取数据信息的措施,爬虫企业应避免通过伪造实名认证或窃取账号密码、内部权限的形式获取数据。

     

    如前文的判决案例,通过技术手段,修改UA、修改device id、绕开网站访问频率控制等,进行数据抓取,如果被定罪,这些技术手段都是违法行为的佐证。

     

    三、非法侵入计算机信息系统罪,合规建议:

    对大数据公司,特别是大数据风控企业来说,获取“裁判文书网”“执行信息公开网”的数据非常普遍且重要,但爬取这类国家事务网站的信息时应当尤为审慎,特别是在网站已采取相关“反爬措施”的情况下,仍强行恶意突破防护措施爬取数据,对网站运行造成影响的,均可能构成本罪。

     

    除上述法律风险以外,利用爬虫技术手段还可能产生构成不正当竞争、侵犯信息网络传播权等法律风险。

     

     

    06

    写在末尾的话

     

    不论你所在公司属于哪个行业,请谨记以下三点:

     

    了解规则,敬畏法律。中国程序员对于法律的集体不敬畏,已经到了令人咋舌的程度。某涉事程序员,坚持认为技术无罪,拒绝配合警方调查,错过了取保侯审的机会,导致被拘留数月,等待判决。

     

    弄清楚公司业务的合法性。之前有P2P业务的集体爆雷,再到被全面禁止ICO业务,还有在线博彩等等,许多程序员醉心专研技术,缺乏法律常识,更缺乏自我保护意识,糊里糊涂成为某些黑心老板的替罪羊。

     

    积极配合警方调查。实事求是地说自己的问题,把客观证据准备好,积极提供给办案机关;切忌满口“我认为”“我感觉”“我猜测”,对于自己主观判断的东西,尽量思考清楚。

     

    最后,愿每个程序员都能用技术去改变世界,让我们的生活变得更加美好!

     

     -End- 

    作者简介K,知名电商公司技术老K级人物。武做过CTO,文出过畅销书,带你一起洞见技术新时代。

    CSDN学院邀请本文作者:老K,共同推出《给技术人的管理课20讲》已经上线了一起跟大咖学习技术和管理,猛击链接前往:https://edu.csdn.net/course/detail/25485

     

     

    展开全文
  • 爬虫到底违法吗?这位爬虫工程师给出了答案

    万次阅读 多人点赞 2019-08-19 11:05:04
    大家好,本期将为大家来采访一位爬虫工程车 一、先简单自我介绍一下 二、为什么选择爬虫 三、

    六月分享主题:爬虫
    HTTP详解
    网页结构简介
    一文带你了解爬虫

    大家好,本期将为大家来采访一位爬虫工程师,与他相识是在一个技术号主群中,只有他怼了我的文章,所以也算不打不相识!他便是小周码字号主:Loco。
    在这里插入图片描述
    文章主要分为三部分,第一部分为Loco自述:简单讲述一下他是如何从大学生一步一步走到现在。第二部分为提问解答:猪哥收集了近100个问题,然后由Loco大佬自行选择回答,快看看你有没有被翻牌吧!第三部分是猪哥从Loco回答中提取的一些关键字,希望能加深大家的记忆。

    一、自述

    1.关于大学

    我读的大学是个野鸡学校,虽说是一个计算机专业,但实际的课程内容很杂。CAD、3DMAX、Office全家桶之类的都会有,所以在校期间对编程方面的成长并不大,当时也就只有写个批量改文件名的工具这种水平。

    毕业以后到目前为止也就在两家公司工作过,一家是上家公司,另一个是现在这家,总体路程还算顺利吧,没遇到过什么大的挫折,各种需求也能逼着自己成长。

    2.接触爬虫

    我接触爬虫这方面的起因,其实是因为找实习,当时快毕业了嘛,要先找个实习锻炼锻炼。但是因为我认为我能做的方向比较多,也还没有想好到底往哪个方向发展比较好,所以就开始看知乎的相关回答,然后发现数据相关的好像都不错,爬虫这个方向看起来也挺有意思的,就边学边开始海投简历。

    投着投着我就发现了一个问题,投简历这个事情太机械化了,能不能写个程序帮我自动投?我就可以腾出这部分时间来干点别的事情了,这样还能顺便练一练写爬虫的技术。

    万幸的是,当时的拉勾、智联、实习僧、58等招聘网站的反爬基本没有,对于一个初学爬虫的人来说还是可以轻松地自己解决:搜索-> 获取职位详情->投递简历这个操作的。

    于是,一个自动投简历的小工具就诞生了,虽然代码十分简陋,完全就是用requests库以一个流程化的方式写下来的,但已经足够达到我想要的效果了。在那之后,我每天就只需要等待面试通知和电话面试,发现有合适的就去面试一下就好了,节省了大量的时间用在搞项目上。
    在这里插入图片描述

    3.第一家公司

    然后大概这么投了一个多星期吧,中间面了十多个公司,有大有小,但都是要么不太满意、要么对应方向的技术深度还不够,直到碰到了上家公司。那是一家创业公司,可能因为创始人是做技术出身的关系吧,公司氛围很不错,跟老板聊起来也很舒服,然后公司本身也是专门做爬虫相关产品的,所以就去了这家公司。

    在这家公司的那段时间应该是我技术水平成长最快的时候了,因为每天做的事情就是写爬虫,当时我们团队将应用商店排名前100的所有APP都“弄”了。什么乱七八糟的问题都有碰到过,然后因为团队里每个人有天赋的方向都不同,一边被需求逼着查各种资料、挑战自己,一边互相补充知识,成长速度就非常快了
    在这里插入图片描述

    4.目前

    从那离职以后我进了现在这家公司,目前做的主要就是区块链搜索引擎的数据收集。看似简单但实际还是很有挑战性的,因为区块链的特性会导致数据量非常大,而且区块链还不像传统互联网网站那样有个标准化的HTML,存在着各种麻烦的问题。所以对于我自己的技术水平增长速度也是有很大的影响的。

    总结一下其实还是那句话,需求逼的。
    在这里插入图片描述

    二、解答

    在采访大佬的时候,我在朋友圈征集了大概100个问题,以下是大佬随机挑选的21个比较有代表性的问题进行解答。

    注:以下“爬虫”均指“垂直爬虫”

    1.非爬虫方向的技术转行做爬虫是否可行?

    可行,而且有一定的基础会很容易上手,至于深入的部分就看自己了。

    2.非技术转行做爬虫是否可行?

    可行,但我认为较难,因为爬虫做深了以后是需要你了解各种相关领域知识的,而你现在对这些领域的东西一无所知,甚至可能连编程都还不知道怎么开始,起点会比有基础的人低很多。

    3.爬虫工作日常如何?加班多不多?

    这个得看公司的,有些公司搞得都是些天天更新反爬的平台(比如工商信息相关的),那基本就是得一直盯着看会不会出问题,一不小心就会要加班。

    4.爬虫对于学生党的用处体现在哪些地方?

    这个问题看个人,因为爬虫技术可用的地方太多了,没法一个一个地都拿出来说。比如你想搞个自动签到的工具,这其实本质上就是爬虫;比如你想搞个自动回复设定内容的机器人,这其实本质上也是爬虫。

    5.学到什么程度才能入职爬虫工程师?

    我觉得首先发请求不用说了吧?抓包工具的使用也不用说了吧?熟练掌握XPath、正则表达式这种解析工具也是基本的,然后JSON之类的传输格式至少要了解过长啥样吧,再就是JS逆向总得会一点吧(从只改变量名函数名混淆级别的代码中找出加密参数生成部分的程度)。差不多会这些以后,再自己做几个项目,应聘个初级爬虫工程师没啥问题。

    6.如何成为一名优秀的爬虫工程师?

    垂直爬虫做到后面本质上就是逆向,你需要有良好的逆向思维方式,并且对一些安全领域的骚东西也有一定的了解,这样你才能游刃有余地处理高难度的反爬。

    7.学爬虫的学习路线?

    上面的入职水平了解一下?然后就是可以关注一下我的公众号「小周码字」(猪哥强力推荐)学习进阶内容,网上其他的教程绝对没有讲得这么细的。

    8.大约学习并从事爬虫几年才可以达到一个不错的高度?

    这个问题也很看个人,我觉得主要看有没有需求逼迫成长吧。之前招人的时候,很多三年经验的也就比入门水平稍微好一点,他们在工作时所遇到的难点几乎全是依靠自动化测试工具,对逆向水平毫无增长。所以建议还是多依靠逆向手段去解决问题,成长速度会很快

    9.薪资方面如何,在几年内可以达到15K?

    同上,标15K及以上的招聘JD还是挺多的,看看招聘需求就知道大概到什么程度了。

    10.面试爬虫哪些技能点是加分项?

    丰富且有深度的逆向经验、熟悉通信协议底层实现、做过骚东西等各种,但主要还是逆向经验。
    在这里插入图片描述

    11.作为一名爬虫工程师,对该岗位的前景如何看待?

    未来主要内容在APP上的平台应该会越来越多,难度也会越来越高,所以对于爬虫工程师的逆向水平要求会越来越高,只会简单逆向甚至不会逆向的人找工作会越来越难。

    12.爬虫和数据挖掘是一样的吗?

    不一样,爬虫只是将数据取回来,具体怎么分析才是数据挖掘的事情。

    13.爬虫是否和黑客差不多?

    差很多,与上个问题类似,只不过“黑客”这个词太宽泛了,黑客也是有具体方向的。

    14.千奇百怪的验证码只能对接打码平台吗?有啥其他办法?

    自己破呗,逆向+机器学习。

    15.现在有用pyppeteer吗?还是一直是selenium?

    都不用,因为效率太低了。

    16.如何爬xx平台?

    涉及法律问题,这种针对某个平台的东西是不能细说的。

    17.爬虫违法吗?如何避免过线导致的违法?怎么规避法律风险?

    算是擦边球吧,其实你即使遵守规则去爬别人的网站,只要人家想搞你,还是可以让你做的事情变成违法的。所以建议不要做太过分的事情,毕竟狗急了也会跳墙。

    还有就是不要为一些明显是做灰黑产的人/公司写代码,一旦他们出事了,你也会被牵连。

    知乎上之前那个很火的被抓了的人,从回答内容中来看其实就是做打码平台的那个微凉,他这一个平台据说赚了至少千万,主要应该是提供给做黑产的人使用了,这种其实被抓是迟早的事。最好的避免违法的办法就是明显觉得不太好的事情就不要去碰,基本就不会有啥问题。

    18.如何有目的地爬取到真正想要的数据?

    让需要数据的人提需求,如果你自己就是那个需要数据的人,那就去做市场调研,看看你需要的数据在哪里能找到。
    在这里插入图片描述

    19.反爬虫最先进的技术是什么?最有效的技术是什么?

    最先进的技术其实就是使用在PC平台上已经玩烂的各种反破解技术将行为监测点(设备指纹、用户操作等)隐藏起来,然后传给服务端做行为识别,如果操作非人类或者缺少某些东西就触发风控。

    最有效的技术其实不是技术而是方法,这个方法就是账号收费,将你的数据变成需要花多少钱才能看到这样子的,就能做到啥高端技术都不用上、轻松提高爬虫方的获取数据成本的效果,当然这也需要结合良好的产品设计,否则普通用户的体验会很差。

    20.请问在xx领域有哪些应用?

    这个应该是对应领域的人自己思考一下自己拿到那些公开数据究竟可以做什么。

    21.需要大量账号的平台成本过高该怎么办?

    人家就是依靠这种方式来提高你成本的,你如果觉得成本过高要么放弃要么换一条路线获取数据。

    三、关键字

    1.实践

    Loco在投简历时直接使用爬虫进行投简历,实习就有这种骚操作,让我明白一个道理:实践是获得高薪的一个捷径!

    2.需求逼的

    和Loco大佬深有同感,尤其在最开始工作的那几年,需求是推动学习成长最快的方法,不逼一把自己,怎么知道你的上限有多高?

    3.逆向

    和多位爬虫工程师交流过,一致认为逆向是最重要的一项技能,后面猪哥也会多学习并写一些逆向方面的教程!

    4.法律意识

    爬虫本身就是打法律的擦边球,所以作为技术人我们更应该守住底线,向灰黑色产业说不。如果有些东西你不能确认是不是违法,可以向身边朋友咨询或者百度,切莫存侥幸心理!

    四、感谢

    最后感谢Loco大佬在百忙中抽出时间接受猪哥的采访,猪哥也看过他的一些爬虫教程,目前很少有人会讲爬虫的逆向,而他是其中一位!

    更多爬虫知识及案例,敬请扫描下方二维码关注猪哥爬虫专栏!
    在这里插入图片描述

    展开全文
  • 对于很多对于不懂编程语言的GGMM来说,爬虫技术高深莫测。但是对于IT工程师来说,爬虫技术可以说信手拈来。虽然熟知爬虫技术,你是否知道它竟然可以做这么多这么牛逼哄哄的事情! 1.利用爬虫技术抓取公司用户信息 ...
  • “一个程序员写了个爬虫程序,整个公司200多人被端了。” “不可能吧!” 刚从朋友听到这个消息的时候,我有点不太相信,做为一名程序员来讲,谁还没有写过几段爬虫呢?只因写爬虫程序就被端有点夸张了吧。 朋友...
  • 程序员有时候很难和外行人讲明白自己的工作是什么,甚至有些时候,跟同行的人讲清楚“你是干什么的”也很困难。比如我自己,就对Daivd在搞的语义网一头雾水。所以我打算写一篇博...
  • 爬虫(一)网络爬虫/相关工具与知识

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

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

    万次阅读 多人点赞 2019-06-28 09:17:50
    相信各大高校应该都有本校APP或超级课程表之类的软件,在信息化的时代能快速收集/查询自己想要的咨询也是种很重要的能力,所以记下了这篇博客,用于总结我所学到的东西,以及用于记录我的第一个爬虫的初生。...
  • Python爬虫的N种姿势

    万次阅读 多人点赞 2019-06-17 09:52:54
      前几天,在微信公众号(Python爬虫及算法)上有个人问了笔者一个问题,如何利用爬虫来实现如下的需求,需要爬取的网页如下(网址为:https://www.wikidata.org/w/index.php?title=Special:WhatLinksHere/Q5&...
  • python爬虫入门到精通全套

    万次阅读 2016-12-09 14:29:45
    https://zhuanlan.zhihu.com/p/21479334
  • Python爬虫入门教程导航帖

    万次阅读 多人点赞 2020-09-22 10:51:57
    Python爬虫入门教程导航,目标100篇。 本系列博客争取把爬虫入门阶段的所有内容都包含住,需要你有较好的Python基础知识,当然你完全零基础也可以观看本系列博客。 Python爬虫入门教程,加油!
  • 这个博客主要是上一个项目的...本博客主要内容如下目录爬虫小技巧一、表达式二、Urllib模块三、requests模块四、实用框架Scrapy 爬虫小技巧 点击查看此文章:常用39个User-Agent代理 一、表达式 网络爬虫基础,学...
  • Python爬虫(一):编写简单爬虫之新手入门

    万次阅读 多人点赞 2019-07-31 09:34:35
    相信很多人是不会的,今天写一个针对新手入门想要学习爬虫的文章,希望对想要学习的你能有所帮助~~废话不多说,进入正文! 一、准备工作 1、首先代码使用python3.x编写的,要有一个本地的python3环境。 pyt...
  • 零基础如何学爬虫技术?

    千次阅读 2016-07-09 15:40:04
    路人甲 ,教你如何编程 190 人赞同 第一:Python爬虫学习系列教程(来源于某博主...一、爬虫入门 ...1. Python爬虫入门一之综述 ...2. Python爬虫入门二之爬虫基础了解 ...3. Python爬虫入门三之Urllib库的基本
  • python爬虫入门教程(一):开始爬虫前的准备工作

    万次阅读 多人点赞 2019-10-28 14:32:40
    python爬虫(数据采集)入门教程
  • Python爬虫学习系列教程

    千次阅读 2015-12-24 20:30:30
    大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多。学习过程中我把一些学习的笔记总结下来,还...1. Python爬虫入门一之综述 2. Python爬虫入门二之爬虫基础了解 3. Python爬虫入
1 2 3 4 5 ... 20
收藏数 38,000
精华内容 15,200
关键字:

爬虫