• requests的安装与简单运用


    requests是python的一个HTTP客户端库,跟urllib,urllib2类似,那为什么要用requests而不用urllib2呢?官方文档中是这样说明的:

    python的标准库urllib2提供了大部分需要的HTTP功能,但是API太逆天了,一个简单的功能就需要一大堆代码。

    我也看了下requests的文档,确实很简单,适合我这种懒人。下面直接看文档。

    http://cn.python-requests.org/zh_CN/latest/user/quickstart.html

    看下他的强大之处:

    1、原始爬虫

    最原始的爬虫爬虫可以只是发送一个HTTP请求,并获取返回的响应数据,使用Requests三行就可以写出一个简单的爬虫,代码如下:

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

    2、高级爬虫

    给原始爬虫升级几个技能就可以投入使用了,我经常升级以下几个功能。

    2.1 获取特定字段: BeautifulSoup+Requests

    BeautifulSoup可以将HTML解析为DOM树,然后获取特定字段。关于BeautifulSoup的详细内容可以看这篇文章,这里只举一个简单的例子。

    以下是途牛某游玩页面的部分代码

    <div class="des">
        <h1 class="mb_10">玉渊潭樱花节</h1>
        <p class="address mb_5"><em class="c_999">地&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 址:</em></p>
        <p class="othmes">
            <span class="t1"><em class="c_999">游玩时间:</em>预计<b class="c_f80">4小时</b></span>
        </p>
    </div>

    可以通过<b class="c_f80">..</b>这个特征来获取4小时这个字段:

    import requests
    from bs4 import BeautifulSoup as bs
    
    url = 'http://www.tuniu.com/play/9232/'
    r = requests.get(url)
    
    soup = bs(r.content)
    print soup.find('b', class_='c_f80').string
    #输出字段有空格,可以通过strip()函数来过滤多余的空格和换行

    注:也可以用requests和lxml的方式抓取。

    2.2 使用代理

    为避免屏蔽,抓取时通常需要代理,使用Requests的proxies参数可以实现这个效果。接上面代码:

    proxies = {
      "http": "http://10.10.1.10:3128",
      "https": "http://10.10.1.10:1080",
    }
    r = requests.get(url, proxies=proxies)

    如果代理需要账户和密码,则需这样:

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

    2.3 模拟百度蜘蛛

    抓取时模拟搜索引擎蜘蛛是个好主意,这里就以User-Agent试图模仿百度蜘蛛去抓取:

    headers = {
        'User-Agent': 'Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)',
    }
    r = requests.get(url, headers=headers)

    3.4 多线程抓取

    为了提高抓取速度,一般都会采用多线程的方式去抓取,可采用了第三方库threadpool的形式实现了多线程。在这里我采用另外一种形式,用标准库multiprocessing来实现:

    import requests
    from bs4 import BeautifulSoup as bs
    from multiprocessing.dummy import Pool as ThreadPool
    
    #URL列表
    urls = [
      'http://www.tuniu.com/play/9232/', 
      'http://www.tuniu.com/play/9231/',
      'http://www.tuniu.com/play/9237/',
      'http://www.tuniu.com/play/9234/',
      # etc.. 
    ]
    
    #提取字段函数
    def get_play_time(url):
        r = requests.get(url)
        soup = bs(r.content)
        print soup.find('b', class_='c_f80').string.strip()
    
    #设置线程数
    pool = ThreadPool(4) 
    
    #开启多线程
    results = pool.map(get_play_time, urls)
    
    #关闭线程并等待结束
    pool.close() 
    pool.join() 

    注:这个多线程的实现主要参考了这篇文章

    2.5 requests+正则

    有时候如果所需字段出现在JS等DOM树之外,可以直接使用正则的方式获取,有时候速度反而会更快一点。

    2.6 抓取网页JS内容

    很多网站会将重点内容放在JS中,增加了抓取的难度。这种可以通过Selenium+PhantomJS+Xpath的方式抓取。有点跑题了……哈哈

  • 相关阅读:
    维护gcd的线段树 补发一波。。。
    BZOJ 4720: [Noip2016]换教室
    P2184 贪婪大陆 树状数组
    BZOJ 1047: [HAOI2007]理想的正方形 单调队列瞎搞
    POJ3280 Cheapest Palindrome 区间DP
    BZOJ 2288: 【POJ Challenge】生日礼物 堆&&链表
    BZOJ 4236: JOIOJI map瞎搞
    浅谈最近公共祖先(LCA)
    题解 BZOJ 1912 && luogu P3629 [APIO2010]巡逻 (树的直径)
    [笔记] 求树的直径
  • 原文地址:https://www.cnblogs.com/feng18/p/5711880.html
Copyright © 2020-2023  润新知