python爬虫第一课,制作搜索引擎

from BeautifulSoup import *
from urlparse import urljoin

ignaorewords=set(['the','of','to','and','a','in','is','it'])

我们的搜索引擎基于关键词, 所以将连词,冠词忽略

下面的代码是爬虫, 将网页的文本数据存储到我们的sqlite中, 大家看不懂也没有关系, 知道这些函数是干什么的就行了

from sqlite3 import dbapi2 as sqlite
import urllib2
class crawler:
    def __init__(self,dbname):
        self.con=sqlite.connect(dbname)
        #连接并建立数据库, dbname 随意, 'xxx.db'就可以
    def __del__(self):
        self.con.close()
    def dbcommit(self):
        self.con.commit()

    def getentryid(self,table,field,value,createnew=True):
        cur=self.con.execute(
            "select rowid from %s where %s='%s'" %(table,field,value))
        res=cur.fetchone()
        if res==None:
            cur=self.con.execute(
                "insert into %s (%s) values ('%s')" % (table,field,value))
            return cur.lastrowid
        else:
            return res[0]

    def addtoindex(self,url,soup):
        if self.isindexed(url): return
        print 'Indexing',url

        #Get words
        text=self.gettextonly(soup)
        words=self.separatewords(text)

        #Get URL id
        urlid=self.getentryid('urllist','url',url)

        # Link word to url
        for i in range(len(words)):
            word=words[i]
            if word in ignaorewords: continue
            wordid=self.getentryid('wordlist','word',word)
            self.con.execute("insert into wordlocation(urlid,wordid,location)             values(%d,%d,%d)" % (urlid,wordid,i))

    def gettextonly(self,soup):
        v=soup.string
        if v==None:
            c=soup.contents
            resulttext=''
            for t in c:
                subtext=self.gettextonly(t)
                resulttext+=subtext+'\n'
            return resulttext
        else:
            return v.strip()

    def separatewords(self,text):
        splitter=re.compile('\\W*')
        return [s.lower() for s in splitter.split(text) if s!='']

    def isindexed(self,url):
        u=self.con.execute(
            "select rowid from urllist where url='%s'" % url).fetchone()
        if u!=None:
            #if crawled
            v=self.con.execute(
                'select * from wordlocation where urlid=%d' % u[0]).fetchone()
            if v != None: return True
        return False

    def addlinkref(self,urlFrom,urlTo,linkText):
        pass

    def crawl(self,pages,depth=2):
        for i in range(depth):
            newpages=set()
            for page in pages:
                try:
                    c=urllib2.urlopen(page)
                except:
                    print "Could not open",page
                    continue
                soup=BeautifulSoup(c.read())
                self.addtoindex(page,soup)

                links=soup('a')
                for link in links:
                    if 'href' in dict(link.attrs):
                        url=urljoin(page,link['href'])
                        if url.find("'") != -1:
                            continue
                        url=url.split('#')[0] #remove location portion
                        if url[0:4]=='http' and not self.isindexed(url):
                            newpages.add(url)
                            linkText=self.gettextonly(link)
                            self.addlinkref(page,url,linkText)
                self.dbcommit()
            pages=newpages

    def createindextables(self):
        self.con.execute('create table urllist(url)')
        self.con.execute('create table wordlist(word)')
        self.con.execute('create table wordlocation(urlid,wordid,location)')
        self.con.execute('create table link(fromid integer,toid integer)')
        self.con.execute('create table linkwords(wordid,linid)')
        self.con.execute('create index wordidx on wordlist(word)')
        self.con.execute('create index urlidx on urllist(url)')
        self.con.execute('create index wordurlidx on wordlocation(wordid)')
        self.con.execute('create index urltoidx on link(toid)')
        self.con.execute('create index urlfromidx on link(fromid)')
        self.dbcommit()

好了, 有了爬虫, 我们再将需要爬取的页面写出来

pagelist=[['http://en.xjtu.edu.cn/'],
          ['http://www.lib.xjtu.edu.cn/'],
          ['http://en.wikipedia.org/wiki/Xi%27an_Jiaotong_University']]

建立数据库

mycrawler=crawler('searchindex.db')
mycrawler.createindextables()

爬取

mycrawler.crawl(pagelist[0])

搜索引擎

class searcher:
    def __init__(self,dbname):
        self.con=sqlite.connect(dbname)

    def __del__(self):
        self.con.close()

    def getmatchrows(self,q):
        # Strings to build the query
        fieldlist='w0.urlid'
        tablelist=''
        clauselist=''
        wordids=[]

        # Split the words by spaces
        words=q.split(' ')
        tablenumber=0

        for word in words:
            #Get the word ID
            wordrow=self.con.execute(
                "select rowid from wordlist where word='%s'" % word).fetchone()
            if wordrow!=None:
                wordid=wordrow[0]
                wordids.append(wordid)
                if tablenumber>0:
                    tablelist+=','
                    clauselist+=' and '
                    clauselist+='w%d.urlid=w%d.urlid and ' % (tablenumber-1,tablenumber)
                fieldlist+=',w%d.location' % tablenumber
                tablelist+='wordlocation w%d' % tablenumber
                clauselist+='w%d.wordid=%d' % (tablenumber,wordid)
                tablenumber+=1

        # Create the query from the separate parts
        fullquery='select %s from %s where %s' % (fieldlist,tablelist,clauselist)
        print fullquery
        cur=self.con.execute(fullquery)
        rows=[row for row in cur]

        return rows,wordids

    def geturlname(self,id):
        return self.con.execute(
            "select url from urllist where rowid=%d" % id).fetchone()[0]

    def normaliszescores(self,scores,smallIsBetter=0):
        vsmall=0.00001
        if smallIsBetter:
            minscore=min(scores.value())
            return dict([(u,float(minscore)/max(vsmall,l)) for (u,l)                        in scores.items()])
        else:
            maxscore=max(scores.values())
            if maxscore==0:
                maxscore=vsmall
            return dict([(u,float(c)/maxscore) for (u,c) in scores.items()])

#score methods
    def frequencyscore(self,rows):
        counts=dict([(row[0],0) for row in rows])
        for row in rows:
            counts[row[0]]+=1
        return self.normaliszescores(counts)

    def locationscore(self,rows):
        locations=dict([(row[0],1000000) for row in rows])
        for row in rows:
            loc=sum(row[1:])
            if loc<locations[row[0]]:
                locations[row[0]]=loc
        return self.normaliszescores(locations,smallIsBetter=1)

    def distancescore(self,rows):
        if len(row[0])<=2:
            return dict([(row[0],1.0) for row in rows])
        mindistance=dict([(row[0],1000000) for row in rows])
        for row in rows:
            dist=sum([abs(row[i]-row[i-1]) for i in range(2,len(row))])
            if dist < mindistance[row[0]]:
                mindistance[row[0]]=dist
        return self.normaliszescores(mindistance,smallIsBetter=1)
#---------------------------------------------------------------------------

    def getscoredlist(self,rows,wordids):
        totalscores=dict([(row[0],0) for row in rows])

        weights=[(1.0,self.frequencyscore(rows))]

        for (weight,scores) in weights:
            for url in totalscores:
                totalscores[url]+=weight*scores[url]
        return totalscores

    def query(self,q):
        rows,wordids=self.getmatchrows(q)
        scores=self.getscoredlist(rows,wordids)
        rankedscores=sorted([(score,url) for (url,score) in scores.items()],reverse=1)
        for (score,urlid) in rankedscores[:10]:
            print '%f\t%s' % (score,self.geturlname(urlid))

建立搜索引擎与数据库的关联

e=searcher('searchindex.db')

搜索

e.query('xjtu college')

这样你的第一个搜索引擎就搭建完毕啦:

1.000000	http://en.xjtu.edu.cn/XJTU_Introduction/Introduction.htm
0.941176	http://en.xjtu.edu.cn/info/1044/1683.htm
0.705882	http://en.xjtu.edu.cn/Schools_and_Colleges.htm
0.529412	http://en.xjtu.edu.cn/info/1044/1681.htm
0.470588	http://en.xjtu.edu.cn/Education/Undergraduate_Education.htm
0.382353	http://en.xjtu.edu.cn/XJTU_News/News.htm
0.382353	http://en.xjtu.edu.cn/Campus_Life/Student_Bodies.htm
0.294118	http://en.xjtu.edu.cn/XJTU_News/Teaching_and_learning.htm
0.294118	http://en.xjtu.edu.cn/info/1044/1572.htm
0.279412	http://en.xjtu.edu.cn/info/1044/1571.htm
时间: 2024-10-06 14:43:59

python爬虫第一课,制作搜索引擎的相关文章

Python作业第一课

零基础开始学习,最近周边的同学们都在学习,我也来试试,嘿嘿,都写下来,下次不记得了还能来看看~~ Python作业第一课1)登陆,三次输入锁定,下次不允许登陆2)设计一个三级菜单,菜单内容可自行定义,任意一级输入q则退出程序,如果输入b则返回上一级 --以上两个题目涉及几个知识点:文档的读取,文档的写入,列表的操作,循环的使用,字符串的一些操作首先回顾一下这几个知识点a)文档的读取,几个常用的f = open("test.log","w")这个w是参数,可换成别的参

Python爬虫——第一个小爬虫01

Python小爬虫——贴吧图片的爬取 在对Python有了一定的基础学习后,进行贴吧图片抓取小程序的编写. 目标: 首先肯定要实现图片抓取这个基本功能 然后要有一定的交互,程序不能太傻吧 最后实现对用户所给的链接进行抓取 一.页面获取 要让python可以进行对网页的访问,那肯定要用到urllib之类的包.So先来个 import urllib urllib中有 urllib.urlopen(str) 方法用于打开网页并返回一个对象,调用这个对象的read()方法后能直接获得网页的源代码,内容与

python学习第一课要点记录

写在要点之前的一段话,留给将来的自己:第一次参加编程的培训班,很兴奋很激动,之前都是自己在网上找免费的视频来看,然后跟着写一些课程中的代码,都是照着模子写,没有自己过多的思考.感觉这样学不好,除了多写以外,还得自己思考,经过了自己思考的源码,才能真正成为自己的东西.在上课前,班主任就让我们自己想一下,通过这个培训,要达到的目标.其实我的目标很简单,不求通过这个培训班能成为什么开发工程师,年薪百万,达到人生巅峰,赢取白富美.那个不现实,我只求能够在现在实际工作中(我的工作主要是网络运维,还兼有系统

初学Python(第一课)

今天整理一下关于Python初学者的基础知识部分的第一课,因为之前学习过C,所以过于基础的知识就不详细记录了. Python相对于C\C++来说,在语法方面已经很简单了:甚至对于JavaScript也是很简单的,减去了很多冗余的部分,让程序的编写更简单便捷. 一.变量 Python变量的定义很简单,Python是动态强类型语言Python省去了定义时的数据类型.C\C++在定义变量的时候都要明确声明该变量的数据类型,如int.char.floor.double.string等等,JavaScri

学习Python爬虫第一步,Bs4库

首先是安装BS4库 因为Python的pip真的很方便,所以一般不出意外,只需要一个pip就足以完成一个库的安装. pip install beautifulsoup4 名字很长不要记错名字呦. 想要利用爬虫获得我们想要的内容,就一定要学会一个解析HTML的库. 我们总不能用正则表达式,匹配出我们需要的内容,那任务量一定是巨大的,繁琐的,很少有人去那么做,除非你就是需要这个网页中特定的元素. 怎么使用BS4库? Bs4库和有些库还有一些不同,像我们学习爬虫一定要学习的requests库,我们只需

python基础第一课

一  python第一个程序 print('hello world!') # python3.x print 'hello world!' # python2.x 二  变量 2.1  变量名称规则 变量名只能是 字母.数字或下划线的任意组合 变量名的第一个字符不能是数字 以下关键字不能声明为变量名 ['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec

学习Python的第一课(简单的单元测试)

由于有C#开发基础,感觉学习Python应该不难,主要是一些语法了,再加上现在互联网这么发达. 感觉还是要有思路,否则学什么也只能是什么. 话不多说,简单发下这几天的学习成果吧: 第一次写博客,大家不要见笑啊 简单的语法就不多说了,随便搜搜就可以得到.() 单元测试来了: 要做两个测试: # 用于判断质数 import math def isPrime(n): print ("验证数字"+str(n)+"是否质数开始") print ("开平方:"

手把手教你写电商爬虫-第一课 找个软柿子捏捏

话说现在基本上大家都在网上买东西,国家经济数据已经可以在网络购物的数据中略微窥见一二,再加上目前B2B行业的持续火爆,大有把所有交易搬到网上来的趋势,这个系列教程就来讲讲如果爬取这些大量的电商交易的数据. 工具要求:教程中主要使用到了 1.神箭手云爬虫框架  这个是爬虫的基础,2.Chrome浏览器和Chrome的插件XpathHelper 这个用来测试Xpath写的是否正确 基础知识:本教程中主要用到了一些基础的js和xpath语法,如果对这两种语言不熟悉,可以提前先学习下,都很简单 教程正式

Python入门第一课——Python的起源、发展与前景!

我们在做任何一件事情之前,我们都会通过各种渠道去搜集事情的信息,了解事情的来龙去脉,学习一门编程语言也是如此,只有知根知底,我们才能有明确的方向和目标,以及底气去完成这件事情,今天我带大家来看看Python的前世今生,希望能够帮助到大家学习Python. 诞生 创始人:Guido van Rossum. 国籍:荷兰. 主要成就:发明 Python 语言. 发明日期:1989年圣诞节. 发明初衷:为了打发圣诞节的无趣,决心开发一个新的脚本解释程序. 名字由来:从作者喜欢的肥皂剧「Monty Pyt