一个简单的爬虫—电影天堂爬虫

无简介

电影天堂是一个下载站,里面有很多经典的电影下载链接,这些链接都可以使用迅雷来下载,今天就来爬一遍这个站,将感兴趣的保存起来。

安装并创建scrapy项目

首先要安装好scrapy,见Python 爬虫进阶三之 Scrapy 框架安装配置 安装好之后,创建一个新的scrapy项目。使用命令:

scrapy startproject dmoz

最后的dmoz是本项目的名字,可以随意命名。

找到或创建爬虫代码文件

项目创建好之后,进入找到一个叫spiders的文件夹,在这个文件夹里面可以找到一个名字中包含spider的py文件,或者自己创建一个放进去也可以,这个py文件,就是爬虫的代码文件,这个里面规定了这个爬虫要怎么去爬去网络的数据,以及如何保存爬去到的东西。

编写爬虫代码

from scrapy.spider import BaseSpider
class DmozSpider(BaseSpider):
name = “dmoz”
allowed_domains = [“www.dytt8.net”]
start_urls = [
http://www.dytt8.net/plus/sitemap.html
]
def parse(self, response):

name属性很重要,不同spider不能使用相同的name start_urls是spider抓取网页的起始点,可以包括多个url,用逗号隔开 parse方法是spider抓到一个网页以后默认调用的callback,避免使用这个名字来定义自己的方法。 当spider拿到url的内容以后,会调用parse方法,并且传递一个response参数给它,response包含了抓到的网页的内容,在parse方法里,你可以从抓到的网页里面解析数据。上面的代码只是简单地把网页内容保存到文件。

在本例中,parse中获得网页的内容之后,解析内容,获得网页中的包含下载链接的内容,保存起来即可。 那么要如何解析获得内容呢? scrapy提供了方便的办法从网页中解析数据,这需要使用到HtmlXPathSelector

    hx = HtmlXPathSelector(response);
    title = hx.xpath("//title/text()").extract()
    sites = hx.xpath('//\*\[@id="Zoom"\]//table//td')
    text = title
    try:
        textStr = str(text\[0\])
    except Exception as e:
        textStr = ""
    urlData = str(response.url)

在这段代码里,我从网页中获得了标签为title的文本内容并赋值到title变量里面 又从网页中寻找id为Zoom的标签,从这个标签里面获得所有的table,从这些table中找td,将这些td都放到了sites里面 然后我将这个网页的地址通过response.url获得之后转化为字符串放到urlData里面 这个时候我已经获得了这个网页里面大部分我需要的东西 然后我只要循环sites来获得每个td里面的内容以及地址就可以了

for sel in sites:
urltext = [t.encode(“utf-8”) for t in sel.xpath(‘a/text()’).extract()]
url = [u.encode(“utf-8”) for u in sel.xpath(‘a/@href’).extract()]
# text = [d.encode(“utf-8”) for d in title]

            try:
                urlStr = str(url\[0\])
            except Exception as e:
                urlStr = ""

            try:
                urlTextStr = str(urltext\[0\])
            except Exception as e:
                urlTextStr=""

urltest是文字,url是下载地址 之后将这写东西保存就可以了,可以写入到本地文件中,也可以连接到数据库直接保存到数据库里面 还有很重要的一点,那就是在爬取的时候在页面中找到的链接都要添加到待爬取列表中,否则只爬取一个页面就断了可不是我们的本意

    hrefs = hx.xpath("//a/@href")
    for href in hrefs:
        if href.extract().find('http')==0:
            url = href.extract()
        else:
            url = urlparse.urljoin(response.url, href.extract())
        yield Request(url, callback=self.parse\_dir\_contents)

这段代码里面首先从网页中找到了所有的a标签,然后获得了a标签的href。 判断这个href里面是否包含http,如果不包含,可能是一个相对地址,也可能是一段js,如果是相对地址,那么就需要补全这个地址,如果不是而是一段js,那加上也没什么问题,最多就是访问不通(最好是加上判断,我这里没有加),然后去这个地址去请求就可以了,之后会一层一层递归,回到最开始,这个遍历的过程就完成了。 注:scrapy会自动判断这个地址是否已经访问过,不用我们去记录

代码

#!/usr/bin/python

-*- coding:utf-8 -*-

from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
from pengpai.items import PengpaiItem
import urlparse
from scrapy.http import Request
import sys
import codecs
import MySQLdb
import datetime

class DmozSpider(BaseSpider):
name = “dmoz”
allowed_domains = [“www.dytt8.net”]
start_urls = [
http://www.dytt8.net/plus/sitemap.html
]
def toSql(self,dataStr):
resultId = -1
db = MySQLdb.connect(“dburl”,“zhanghao”,“mima”,“dbname”)
cursor = db.cursor()
cursor.execute(“SET NAMES utf8”)
cursor.execute(“SELECT VERSION()”)
try:
cursor.execute(dataStr)
resultId = int(db.insert_id())
db.commit()
except:
db.rollback()
db.close()
return resultId
def parse(self, response):
reload(sys)
sys.setdefaultencoding(‘utf-8’)
hx = HtmlXPathSelector(response)
hrefs = hx.xpath(“//a/@href”)
for href in hrefs:
if href.extract().find(‘http’)==0:
url = href.extract()
else:
url = urlparse.urljoin(response.url, href.extract())
yield Request(url, callback=self.parse_dir_contents)
# file_object.close( )

def parse\_dir\_contents(self, response):
    hx = HtmlXPathSelector(response);
    title = hx.xpath("//title/text()").extract()
    sites = hx.xpath('//\*\[@id="Zoom"\]//table//td')
    text = title
    try:
        textStr = str(text\[0\])
    except Exception as e:
        textStr = ""
    urlData = str(response.url)
    resultfile = codecs.open('result.txt','a',"utf-8")
    if(len(sites)>0):
        print(str(len(sites))+"=="+str(response.url))
        #INSERT into movie\_name (movie\_name.\`name\`,movie\_name.url,movie\_name.count) SELECT 'name','http','3' from DUAl WHERE NOT EXISTS (SELECT 1 from movie\_name WHERE movie\_name.url = 'http' and movie\_name.count='3')
        movie\_name = "INSERT into movie\_name (movie\_name.\`name\`,movie\_name.url,movie\_name.count) SELECT '"+textStr+"','"+urlData+"','"+str(len(sites))+"' from DUAl WHERE NOT EXISTS (SELECT 1 from movie\_name WHERE movie\_name.url = '"+urlData+"' and movie\_name.count='"+str(len(sites))+"')LIMIT 1;"
        # file\_object = codecs.open('thefile.txt', 'a',"utf-8")
        resultIDBack = self.toSql(movie\_name)
        resultfile.write(movie\_name)
        resultfile.write('\\n')
        for sel in sites:
            urltext = \[t.encode("utf-8") for t in sel.xpath('a/text()').extract()\]
            url = \[u.encode("utf-8") for u in sel.xpath('a/@href').extract()\]
            # text = \[d.encode("utf-8") for d in title\]

            try:
                urlStr = str(url\[0\])
            except Exception as e:
                urlStr = ""

            try:
                urlTextStr = str(urltext\[0\])
            except Exception as e:
                urlTextStr=""

            
            dt=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            #data = "insert into movie (movie.\`name\`,movie.url,movie.urltext,movie.\`from\`) values (\\""+textStr+"\\",\\""+urlStr+"\\",\\""+urlTextStr+"\\",\\""+urlData+"\\");"
            #INSERT INTO movie\_data (movie\_data.nameId,movie\_data.url,movie\_data.urltext,movie\_data.\`from\`,movie\_data.updateTime) SELECT '1','dizhi','wenzi','laiyuan',NOW() FROM DUAL WHERE NOT EXISTS(SELECT 1 from movie\_data WHERE movie\_data.\`from\` = 'laiyuan' and movie\_data.url = 'dizhi' AND movie\_data.urltext = 'wenzi') LIMIT 1;
            #INSERT INTO movie (movie.\`name\`,movie.url,movie.urltext,movie.\`from\`,updateTime) SELECT '"+textStr+"', '"+urlStr+"', '"+urlTextStr+"', '"+urlData+"', '"+dt+"' FROM DUAL WHERE NOT EXISTS ( SELECT 1 FROM movie WHERE movie.url = '"+urlStr+"' AND movie.\`from\` = '"+urlData+"')LIMIT1;
            data = "INSERT INTO movie\_data (movie\_data.nameId,movie\_data.url,movie\_data.urltext,movie\_data.\`from\`,movie\_data.updateTime) SELECT '"+str(resultIDBack)+"','"+urlStr+"','"+urlTextStr+"','"+urlData+"','"+dt+"' FROM DUAL WHERE NOT EXISTS(SELECT 1 from movie\_data WHERE movie\_data.\`from\` = '"+urlData+"' and movie\_data.url = '"+urlStr+"' AND movie\_data.urltext = '"+urlTextStr+"') LIMIT 1;"
            # file\_object.write("\["+str(text\[0\])+"\]已添加..")
            # file\_object.write('\\n')
            resultfile.write(data)
            resultfile.write('\\n')
            #print(data)
            self.toSql(data)
    hrefs = hx.xpath("//a/@href")
    for href in hrefs:
        if href.extract().find('http')==0:
            url = href.extract()
        else:
            url = urlparse.urljoin(response.url, href.extract())
        yield Request(url, callback=self.parse\_dir\_contents)
    resultfile.close( )
    # file\_object.close( )

好了,这时候只要运行这个爬虫就可以了

scrapy crawl dmoz

这个里面的dmoz就是上面代码中name的那个值

-------------本文结束  感谢您的阅读-------------
下次一定