我爱编程

Python爬取电影天堂数据并存储到本地mongoDB数据库

2017-09-21  本文已影响945人  老汤哥不老

之前一直有想法要爬虫电影天堂的电影资源(http://www.dytt8.net/),今天将这个需求完成,具体效果如下:

1.png

准备工作:本地mongoDB数据库的搭建和可视化工具robo 3t的使用(如已安装可跳过)

(一)下载mongoDB

首先新增mongoDB文件(https://www.mongodb.com/download-center?jmp=nav#atlas),这个网站逼事比较多还要注册账号,自行完成注册下载,本人下载的是这个版本的:mongodb-win32-x86_64-2008plus-v3.4-latest-signed.msi,安装的时候需要注意的时候,用管理员权限打开cmd之类的命令提示符,在“命令提示符(管理员)”中输入"msiexec /package " +"你将要安装的程序的完整路径及程序名"(注意空格),如下图:

2.png

然后按回车进行安装,一直下一步直到结束

(二)配置环境变量

和Python,JAVA类似的方法进行配置。我这里拿自己电脑的路径做示例。大家给自己电脑配置时请根据自己实际的安装目录配置。

3.png

(三)创建及配置数据库存储路径

管理员运行cmd,进入到安装目录bin目录下运行下面命令,配置数据存储路径,在执行代码之前需要在E盘创建data\db目录,这个就是你存储数据的地方

mongod.exe --dbpath E:\data\db
4.png

结束之后cmd窗口别关,继续

mongod.exe --bind_ip 0.0.0.0 --logpath E:\data\logs\mongo.log --logappend --dbpath E:\data\db --port 27017 --serviceName "MongoDB" --serviceDisplayName "MongoDB" --install

需要注意的是 E:\data\logs\mongo.log,D:\data\db。这些目录及文件需手动先创建,这个可以自己安装喜欢放在别的地方,记得代码上的地址要对应上

(四)启动系统服务

打开Windows下服务。找到mongoDB服务,双击打开,点击启动运行

5.png

当然这个还要用代码去运行mongoDB服务的,我这个比较直观简单

(五)安装可视化工具robo 3t

直接去官网下载(https://robomongo.org/download),下载完成之后,一路下一步安装,这个文章写了,http://www.cnblogs.com/dacongge/p/7346037.html 说的还行,可以对着用,连接上之后,才是准备工作结束

分析界面

(一)主要界面分析

电影天堂首页(http://www.dytt8.net/)

6.png

观察网页地址:http://www.dytt8.net/html/gndy/dyzz/index.html
然后我们翻到最后一页:http://www.dytt8.net/html/gndy/dyzz/list_23_165.html
再点下面的页签到首页:http://www.dytt8.net/html/gndy/dyzz/list_23_1.html
在随机任何一页(对齐):http://www.dytt8.net/html/gndy/dyzz/list_23_5.html
是不是发现了规律,有了规律就能进行构成所有页数的链接了

(二)电影详情界面分析

在首页(http://www.dytt8.net/html/gndy/dyzz/list_23_1.html),分析<神奇女侠>这部电影,以及<神偷奶爸>这两部电影的html,发现对应的a标签的class都是一样的,而且href的链接需要拼接,找到规律之后,后面就好弄了

7.png 8.png

跳转到电影详情界面,我们需要这个界面上的电影的标题,和迅雷下载链接

9.png 10.png

F12查看网页源码
标题的内容比较好拿到,class="title_all"下面的h1标签就能拿到标题

11.png

迅雷下载链接

12.png

全局搜索发现td的style的内容是唯一的,可以通过BeautifulSoup去拿到td下面的a的内容
好了,大部分的内容都可以简单的拿到,那我们就开始写代码吧

代码编写

用到的类库:
urllib2
BeautifulSoup
pymongo
gevent(子线程 解释:http://python.jobbole.com/85438/)
sys
编码大致思路:
1.从第一页开始获取,获取每一页电影链接
2.通过电影链接到电影详情界面获取电影的详情信息
3,获取结束之后,存储到mongoDB

# -*- coding: UTF-8 -*-
import urllib2
import sys
from bs4 import BeautifulSoup
from pymongo import MongoClient
import gevent
from gevent import monkey
import socket

socket.setdefaulttimeout(60)

#访问url,返回html页面
def url_open(url):
    try:
        req=urllib2.Request(url)
        req.add_header('User-Agent','Mozilla/5.0')
        response=urllib2.urlopen(url)
        html=response.read()
        return html
    except BaseException as f:
        print('获取HTML文本失败,错误信息为',f)

#获取每页HTML文本内电影链接
def get_url(html):
    try:
        soup = BeautifulSoup(html,'lxml')
        urlslist = soup.find_all('a',class_='ulink')

        for url in urlslist:
            url = 'http://www.dytt8.net' + url['href']
            yield url
    except BaseException as f:
        print('获取URL失败,错误信息为',f)

#从html页面中获取视频下载地址
def get_download_url(broken_html):
    soup=BeautifulSoup(broken_html,'html.parser')
    td=soup.find('td',attrs={'style':'WORD-WRAP: break-word'})
    url_a=td.find('a')
    url_a=url_a.string
    return url_a

def get_info(url):

    try:
        date = {}
        html = url_open(url)
        html = html.decode('gb2312','ignore').encode('utf-8','ignore')
        soup = BeautifulSoup(html,'html.parser')
        title = soup.find('h1').string
        print ('电影名称' + title)

        download_url = get_download_url(html)
        print ('迅雷链接' + download_url)

        date['电影名称'] = title
        date['电影详情链接'] = url
        date['迅雷链接'] = download_url


        return date
    except BaseException as f:
        print('获取下载链接出错了,错误信息为:',f)


def main(pages):

    try:
        #数据库连接
        conn = MongoClient('127.0.0.1', 27017){}.html'.format(str(page))
        db = conn.films
        movies = db.movies
        for page in pages:
            first_url = 'http://www.dytt8.net/html/gndy/dyzz/list_23_{}.html'.format(str(page))
            print('正常处理:{}'.format(first_url))
            html = url_open(first_url)

            for url in set(get_url(html)):
                print('正在保存链接:{}的数据'.format(url))
                date = get_info(url)
                movies.insert(date)
    except BaseException as f:
        print('主程序运行出错了,错误信息为:',f)


if __name__=='__main__':
    reload(sys)  # 2
    sys.setdefaultencoding('utf-8')

    urllist = list(range(165))
    #多线程处理
    monkey.patch_all()
    jobs=[]
    for i in  range(165):
        job = None
        job = gevent.spawn(main, urllist[i:165])
        jobs.append(job)
    gevent.joinall(jobs)
    print('----------全部保存成功----------')

本人多次测试之后发现,很多迅雷链接的地址无法抓取到,只有最近的两百多部电影可以获取到,所以,在数据存储的时候,只会有两百多部电影可以存在数据库,这个结果控制台和数据库的数字是一致的

13.png

结果

14.png

如有问题可以提出,初学者还望大神多多指教

上一篇 下一篇

猜你喜欢

热点阅读