美文网首页
Python爬虫--真实世界的网页解析

Python爬虫--真实世界的网页解析

作者: LineWay | 来源:发表于2016-05-27 17:38 被阅读0次

    用Requests + BeautifulSoup 爬取Tripadvistor

    爬取一个网页需要两步:
    1.服务器与本地的接交换机制
    2.解析真实网页的方法

    1.服务器与本地的交换机制

    浏览网页的过程是通过浏览器向网站所在的服务器发送一个Request,同时服务器回应一个Response,这就是一个简单的HTTP协议
    每一个Request请求包括很多种方法,目前(HTTP2.0)的方法有:getpostheadputoptionsconnecttracedelete,这八种方法。 GET和POST是最常用的两种方法。
    爬虫抓取一个网页,实质上就是模拟这两种方法。

    GET/page_one.html HTTP/1.1 Host:www.sample.com
    以上是一个简单的get方法发送的请求方式,可以看出请求得到的信息包括页面的内容,协议的版本信息,以及网页的主域名。

    一个正常打开的页面,返回的状态码应该是200,无法打开的页面一般返回403或者404

    2.爬取Tripadvisor页面信息

    爬取页面信息的步骤:
    1.导入所需要的库
    2.使用requests请求要爬取的网页
    3.解析网页
    4.描述要爬取的元素位置

    #_*_ coding:utf-8 _*_
    
    
    from bs4 import BeautifulSoup
    import requests
    import time
    
    
    # part1
    '''
    url = 'http://www.tripadvisor.cn/Attractions-g60763-Activities-New_York_City_New_York.html'
    wb_data = requests.get(url)
    soup = BeautifulSoup(wb_data.text, 'lxml')
    # 1.描述要爬取元素的位置
    # Copy一下title的selector,测试一下结果
    # titles = soup.select('#ATTR_ENTRY_105127 > div.property_title > a')
    # print titles
    # 打开原网页,查找title的父标签样式,发现在每一个<div class="property_title">下面的<a>标签中的内容就是title
    # 那么更新一下titte的解析语句
    titles = soup.select('div.property_title > a[target="_blank"]')
    
    # 2.筛选所需要的元素
    # 页面中存在的图片不一定全是所需要的,可以根据图片的属性(大小)对图片进行筛选
    imgs = soup.select('img[width="160"]')
    
    # 对其他的元素进行筛选
    # tags一般是多对一的关系,所以在tags的父类标签进行筛选
    cates = soup.select('div.p13n_reasoning_v2')
    
    # 3.整理并筛选所需信息
    
    for title, img, cate in zip(titles, imgs, cates):
        data = {
            'title': title.get_text(),
            'img': img.get('src'),
            'cate':list(cate.stripped_strings)
        }
        print data,'\n*************************************\n'
    # 运行上述代码后发现,爬取的图片链接是一样的,也就意味着图片信息没有爬取下来
    # 这是由于站点的反爬虫机制造成的,站点的图片加载是通过JavaScript控制的,暂时先不用管这些
    
    # 4.使爬虫为登录站点的状态,构造向服务器提交的参数:headers
    # 重新完成一个爬虫代码
    '''
    
    # part2
    '''
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36',
        'Cookie':'__utma=55896302.1244431692.1455603774.1455603774.1455603774.1; __utmc=55896302; =',
    
    }
    url_saves = 'http://www.tripadvisor.cn/Saves#207971'
    wb_data = requests.get(url_saves, headers=headers)
    soup = BeautifulSoup(wb_data.text, 'lxml')
    
    titles = soup.select('a.location-name')
    imgs = soup.select('img.photo_image')
    metas = soup.select('span.format_address')
    
    for title, img, meta in zip(titles, imgs, metas):
        data = {
            'title':title.get_text(),
            'img':img.get('src'),
            'meta':list(meta.stripped_strings),
        }
        print data
    
    '''
    
    
    # 构造函数
    
    url_saves = 'http://www.tripadvisor.cn/Saves#207971'
    url = 'http://www.tripadvisor.cn/Attractions-g60763-Activities-New_York_City_New_York.html'
    # 连续爬取30页的网页信息,发现每一页的区别在于 oa30 这个参数上,每一页的站点在这个数值的基础上增加30
    # 所以可以用以下的格式进行爬取
    urls = ['http://www.tripadvisor.cn/Attractions-g60763-Activities-oa{}-New_York_City_New_York.html#ATTRACTION_LIST'.format(str(i)) for i in range(30,930,30)]
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36',
        'Cookie':'__utma=55896302.1244431692.1455603774.1455603774.1455603774.1; __utmc=55896302; =',
    }
    
    def get_attractions(url, data=None):
        wb_data   = requests.get(url)
        time.sleep(4)
        soup      = BeautifulSoup(wb_data.text, 'lxml')
        titles    = soup.select('div.property_title > a[target="_blank"]')
        imgs      = soup.select('img[width="160"]')
        cates     = soup.select('div.p13n_reasoning_v2')
        for title, img, cate in zip(titles, imgs, cates):
            data = {
                'title':title.get_text(),
                'img': img.get('src'),
                'cate':list(cate.stripped_strings),
            }
            print data,'\n','*'*50,'\n'
    
    
    def get_favs(url, data=None):
        wb_data = requests.get(url, headers=headers)
        soup    = BeautifulSoup(wb_data.text, 'lxml')
        titles  = soup.select('a.location-name')
        imgs    = soup.select('img.photo_image')
        metas   = soup.select('span.format_address')
    
        if data == None:
            for title, img, meta in zip(titles, imgs, metas):
                data = {
                    'title':title.get_text(),
                    'img':img.get('src'),
                    'meta':list(meta.stripped_strings),
                }
                print data,'\n','*'*50,'\n'
    
    for single_url in urls:
        get_attractions(single_url)
    
    
    # 6.爬取多连续页的资料
    
    
    

    代码演示了简单的爬虫,带Cookie的爬虫,以及连续爬取多个页面的爬虫。

    为了应对站点的反爬虫机制,也可以利用模拟手机端登录的方式进行站点的爬取:

    # 手机端抓取网页信息
    from bs4 import BeautifulSoup
    import requests
    
    
    headers = {
        'User-Agent':'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
    }
    
    url = 'http://www.tripadvisor.cn/Attractions-g60763-Activities-oa30-New_York_City_New_York.html'
    mb_data = requests.get(url, headers=headers)
    soup = BeautifulSoup(mb_data.text, 'lxml')
    imgs = soup.select('div.thumb.thumbLLR.soThumb > img')
    for i in imgs:
        print i.get('src')
    
    
    

    从代码中可以看出,模拟手机端的爬虫与一般的爬虫非常的相似,区别在于headers中的User-Agent是不一样的,这个也是非常简单的,Chrome浏览器可以通过很简单的方式进行手机端登录站点的模拟。具体实现可以在网上查找一下。

    相关文章

      网友评论

          本文标题:Python爬虫--真实世界的网页解析

          本文链接:https://www.haomeiwen.com/subject/cbkfdttx.html