美文网首页
近期的计划-出一系列爬虫的文章2

近期的计划-出一系列爬虫的文章2

作者: nonoBoy | 来源:发表于2017-04-12 17:38 被阅读84次

    月底回青海之前,在造数微信群里帮一位朋友爬了豆瓣电影的数据,分享一下心得:
    1 、豆瓣电影汇总的链接url = 'https://movie.douban.com/tag/'
    2 、通过tag页链接,抓取到所有分类首页链接,代码如下:

    import requests
    from lxml import etree
    
    url = 'https://movie.douban.com/tag/'
    headers = {
        'User-Agent': "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko/20100101 Firefox/11.0"
    }
    
    #获取每个tag对应的url
    def getTagURLs(url):
        response = requests.get(url, headers=headers)
        selector = etree.HTML(response.text)
    
        all_tag = selector.xpath("//div[@class='article']//td//a")
        all_href = selector.xpath("////div[@class='article']//td//a/@href")
    
        for i in range(len(all_tag)):
            tag = all_tag[i].xpath('string(.)')
            href = 'https://movie.douban.com' + all_href[i]
            print(tag + ': ' + href)
    

    运行上面代码打印如下结果:

    类别名: 对应首页链接
    爱情: https://movie.douban.com/tag/爱情
    喜剧: https://movie.douban.com/tag/喜剧
    剧情: https://movie.douban.com/tag/剧情
    动画: https://movie.douban.com/tag/动画
    科幻: https://movie.douban.com/tag/科幻
    动作: https://movie.douban.com/tag/动作
    经典: https://movie.douban.com/tag/经典
    .....

    3、基于以上结果并分析网页很容易构造出所有电影列表的链接:
    例如,爱情类电影所有链接符合规律:
    https://movie.douban.com/tag/爱情?start=0 (第一页)
    https://movie.douban.com/tag/爱情?start=20 (第二页)
    https://movie.douban.com/tag/爱情?start=40 (第二页)
    ...
    构造出所有类别的所有页面链接后,写入Mongodb,后面用作多进程抓取的URL队列;下面基于以上代码获取每个类别总的页数并且构造url写入数据库:

    import requests
    from lxml import etree
    from mongodb_queue import MongoQueue
    
    spider_queue = MongoQueue('douban', 'movie')
    url = 'https://movie.douban.com/tag/'
    
    headers = {
        'User-Agent': "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko/20100101 Firefox/11.0"
    }
    
    #获取每个tag对应的url
    def getTagURLs(url):
        response = requests.get(url, headers=headers)
        selector = etree.HTML(response.text)
    
        all_tag = selector.xpath("//div[@class='article']//td//a")
        all_href = selector.xpath("////div[@class='article']//td//a/@href")
    
        for i in range(len(all_tag)):
            tag = all_tag[i].xpath('string(.)')
            href = 'https://movie.douban.com' + all_href[i]
            print(tag + ': ' + href)
            
            #通过href获得total-page
            response4 = request.get(href, 3)
    
            #sleep
            time.sleep(2.0 + random.random())
            selector4 = etree.HTML(response4.text)
    
            total_page = selector4.xpath("//span[@class='thispage']/@data-total-page")
            total_page = total_page[0]
            print('总的页面数: ' + total_page)
    
            #构造所以列表页面
            for i in range(int(total_page) + 2):
                page = 20 * i
                listURL = href + '?'+ 'start=' + str(page) +'&type=T'
                print(listURL)
                spider_queue.push(listURL)
    

    写入数据库后,URL队列如下:

    { "_id" : "https://movie.douban.com/tag/爱情?start=0", "status" : 1 }
    { "_id" : "https://movie.douban.com/tag/爱情?start=20", "status" : 1 }
    { "_id" : "https://movie.douban.com/tag/爱情?start=40", "status" : 1}
    ......
    
    

    4、基于数据库URL队列,下面开启多进程进行数据抓取(使用代理IP,手动VPN切换IP-几次就能抓完):

    from Download import request
    from mongodb_queue import MongoQueue
    from lxml import etree
    import multiprocessing
    import time
    import random
    
    spider_queue = MongoQueue('douban', 'movie')
    
    def doubanMovieSpider():
        while True:
            try:
                url = spider_queue.pop()
            except:
                print('队列咩有数据')
                break
            else:
                result = getMovies(url)
                #是否抓取成功判断
                if len(result) != 0:
                    spider_queue.complete(url)
                else:
                    spider_queue.reset(url)
    
    def getMovies(url):
        response2 = request.get(url, 3)
        selector2 = etree.HTML(response2.text)
    
        all_names = selector2.xpath("//div[@class='pl2']//a")
        all_description = selector2.xpath("////div[@class='pl2']//p")
        all_urls = selector2.xpath("//div[@class='pl2']//a/@href")
    
        for i in range(len(all_names)):
            name = all_names[i].xpath('string(.)')
    
            # 去空格
            name = ''.join(name.strip())
            # 去掉内部空格
            name = name.replace('\n', '')
            name = name.replace(' ', '')
    
            description = all_description[i].xpath('string(.)')
            href = all_urls[i]
            print('电影名称:' + name + ',电影主页URL:' + href, end='\n')
            print(description)
    
            file4 = open('mydata.txt', 'a')
            file4.write('电影名称:' + name + ',电影主页URL:' + href + '\n' + description + '\n')
            file4.close()
    
        time.sleep(2.0 + random.random())
        return all_names
    
    #多进程
    def process_crawler():
        process= []
        #开启100个进程 期间被封掉了几个IP,用VPN切换IP又可以重新抓取
        #这里使用的方法属于暴力快速抓取
        for i in range(100):
            p = multiprocessing.Process(target=doubanMovieSpider)
            p.start()
            process.append(p)
        for p in process:
            p.join()
    
    if __name__ == "__main__":
        process_crawler()
    

    代码中的Download和mongdb_queue模块参考文章1
    最后分享抓到的电影数据,txt格式大概30M;
    https://pan.baidu.com/s/1mika4Pi
    提取密码:97h7

    具体数据格式参考:

    电影名称:美女与野兽,电影主页URL:https://movie.douban.com/subject/25900945/
    2017-03-17(中国大陆/美国) / 艾玛·沃森 / 丹·史蒂文斯 / 卢克·伊万斯 / 凯文·克莱恩 / 乔什·加德 / 伊万·麦克格雷格 / 伊恩·麦克莱恩 / 艾玛·汤普森 / 斯坦利·图齐 / 古古·姆巴塔-劳 / 奥德拉·麦克唐纳 / 内森·麦克 / 哈蒂·莫拉汉...
    
    电影名称:爱乐之城/星声梦里人(港)/乐来越爱你(台),电影主页URL:https://movie.douban.com/subject/25934014/
    2016-08-31(威尼斯电影节) / 2016-12-25(美国) / 2017-02-14(中国大陆) / 瑞恩·高斯林 / 艾玛·斯通 / 约翰·传奇 / 罗丝玛丽·德薇特 / 芬·维特洛克 / 杰西卡·罗德 / 水野索诺娅 / 考莉·赫尔南德斯 / J·K·西蒙斯 / 汤姆·艾弗瑞特·斯科特 / 米根·费伊...
    ......
    

    相关文章

      网友评论

          本文标题:近期的计划-出一系列爬虫的文章2

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