04 爬虫应用——校园网搜索引擎(2)源码实现

1、信息采集模块——网络爬虫的实现

具体步骤:
(1)获取初始的URL。
(2)根据初始的URL爬取页面并获取新的URL。
(3)将新的URL放到URL队列中。
(4)从URL队列中读取新的URL,然后爬取新网页,重复上述爬取过程。
(5)当满足爬虫系统设置的停止条件时停止爬取。

unvisited = deque()
visited = set()

import sys
from collections import deque
import urllib
from urllib import request
import re 
from bs4 import BeautifulSoup
import lxml
import sqlite3
import jieba
jieba.load_userdict('dict1.txt')
url = 'http://www.zut.edu.cn'
unvisited = deque()
visited = set()
unvisited.append(url)


conn = sqlite3.connect('viewsdu.db')
c = conn.cursor()

c.execute('drop table doc')
c.execute('create table doc(id int primary key, link text)')
c.execute('drop table word')
c.execute('create table word(term varchar(25) primary key, list text)')
conn.commit()
conn.close()


print('********************开始爬取**********************')
cnt = 0
print('开始。。。。')
while unvisited:
    url = unvisited.popleft()
    visited.add(url)
    cnt += 1
    print('开始抓取第',cnt , '个链接:', url)
    
    #     爬取网页内容
    try:
        reponse = request.urlopen(url)
        content = reponse.read().decode('utf-8')
    except:
        continue
        
    soup = BeautifulSoup(content, 'lxml')
    all_a = soup.find_all('a',{'class':"menu0_1_"}) # 找到a标签
#     print(all_a, cnt)
    
    # 筛选合格网页的过程
    for a in all_a:
        x = a.attrs['href']                  # 读取a标签的属性href的值(网页值)
        if re.match(r'http.+', x):
            if not re.match(r'http\:\/\/www\.zut\.edu\.cn\/.+', x):
                continue # 这个格式不要改造直接保留下来使用!!!
        if re.match(r'.*?\.htm', x):
            x = 'http://www.zut.edu.cn/'+ x
        elif re.match(r'xxgk/.+', x):
            x = 'http://www.zut.edu.cn/' +x
        elif re.match(r'\.\.\/info/.+', x):
            x = 'http://www.zut.edu.cn' + x[2:]
        elif re.match(r'\.\.\/\.\.\/info/.+', x):
            x = 'http://www.zut.edu.cn' + x[5:]
        
        if (x not in visited) and (x not in unvisited):
            unvisited.append(x)
            
            
    a = soup.find('a') #, {'class': 'Next'}
    if a != None:
        x = a.attrs['href']
        if re.match(r'xwdt\/.+', x):
            x = 'http://www.zut.edu.cn/index/'+ x
        else:
            x = 'http://www.zut.edu.cn/index/xwdt/' + x
        if (x not in visited) and (x not in unvisited):
            unvisited.append(x)
            
#    2、索引模块——建立倒排词表   
#   解析网页内容,一定要根据该网页的具体情况来处理!!!!!
    soup = BeautifulSoup(content, 'lxml')
    title = soup.title
    article=soup.find('p') # class_='c67215_content',id='vsb_newscontent'
    author = soup.find('span')  # class_ = 'authorstyle67215'
    time = soup.find('span') # , class_ = 'timestyle67215'
    if title == None and article == None and author == None:
        print('无内容的页面。')
        continue
    elif article == None and author == None:
        print('只有标题。')
        title = title.text
        title = ''.join(title.split())
        article = ''
        author = ''
    elif article == None:
        print('有标题有作者,缺少内容')
        title = title.text
        title = ''.join(title.split())
        article = ''
        author = author.get_text('', strip=True)
        author = ''.join(author.split())
    elif author == None:
        print('有标题有内容,确实作者')
        title = title.text
        title = ''.join(title.split())
        article = article.get_text('', strip=True)
        article = ''.join(article.split())
        author = ''
    else:
        title = title.text
        title = ''.join(title.split())
        article = article.get_text('', strip=True)
        article = ''.join(article.split())
        author = author.get_text('', strip=True)
        author = ''.join(author.split())
    print('网页标题:', title)
    
    
#     并对每个分出的词语建立倒排词表:
    seggen = jieba.cut_for_search(title)
    seglist = list(seggen)
    seggen = jieba.cut_for_search(article)
    seglist += list(seggen)
    seggen = jieba.cut_for_search(author)
    seglist += list(seggen)
    
    
#     数据存储
    conn = sqlite3.connect('viewsdu.db')
    c = conn.cursor()
    c.execute('insert into doc values(?,?)', (cnt, url))
    for word in seglist:
        c.execute('select list from word where term=?',(word,))
        result = c.fetchall()
        
        if len(result) == 0:
            docliststr = str(cnt)
            c.execute('insert into word values(?,?)', (word, docliststr))
            
        else:
            docliststr = result[0][0]
            docliststr += ' ' + str(cnt)
            c.execute('update word set list=? where term=?', (docliststr, word))
    
    conn.commit()
    conn.close()
    
print('词表建立完毕!!')

开始爬取**
开始。。。。
开始抓取第 1 个链接: http://www.zut.edu.cn
网页标题: 中原工学院
开始抓取第 2 个链接: http://www.zut.edu.cn/index.htm
网页标题: 中原工学院
开始抓取第 3 个链接: http://www.zut.edu.cn/xxgk.htm
网页标题: 学校概况-中原工学院
开始抓取第 4 个链接: http://www.zut.edu.cn/xybm1.htm
网页标题: 学校部门-中原工学院
开始抓取第 5 个链接: http://www.zut.edu.cn/xwgk.htm
网页标题: 校务公开-中原工学院
开始抓取第 6 个链接: http://www.zut.edu.cn/rcyj.htm
网页标题: 人才引进-中原工学院
开始抓取第 7 个链接: http://www.zut.edu.cn/zsjy1.htm
网页标题: 招生就业-中原工学院
开始抓取第 8 个链接: http://www.zut.edu.cn/wlfw.htm
网页标题: 网络服务-中原工学院
开始抓取第 9 个链接: http://www.zut.edu.cn/xxgk/xxjj.htm
网页标题: 学校简介-中原工学院
开始抓取第 10 个链接: http://www.zut.edu.cn/xxgk/ywjj.htm
网页标题: 英文简介-中原工学院
开始抓取第 11 个链接: http://www.zut.edu.cn/xxgk/xxls.htm
网页标题: 历史沿革-中原工学院
开始抓取第 12 个链接: http://www.zut.edu.cn/xxgk/xxts.htm
网页标题: 现任领导-中原工学院
开始抓取第 13 个链接: http://www.zut.edu.cn/xxgk/xzxx.htm
网页标题: 校训校风-中原工学院
开始抓取第 14 个链接: http://www.zut.edu.cn/xxgk/xxxg.htm
网页标题: 学校校歌-中原工学院
开始抓取第 15 个链接: http://www.zut.edu.cn/xwgk/xwgkzn.htm
网页标题: 校务公开指南-中原工学院
开始抓取第 16 个链接: http://www.zut.edu.cn/xwgk/xwgkxx.htm
网页标题: 校务公开信息-中原工学院
开始抓取第 17 个链接: http://www.zut.edu.cn/hzjl1/zwhzbxxxgsl.htm
网页标题: 中外合作办学信息公示栏-中原工学院
开始抓取第 18 个链接: http://www.zut.edu.cn/index/xwdt/javascript:setHomepagea67222a()
开始抓取第 19 个链接: http://www.zut.edu.cn/…/index.htm
开始抓取第 20 个链接: http://www.zut.edu.cn/…/xxgk.htm
开始抓取第 21 个链接: http://www.zut.edu.cn/…/xybm1.htm
开始抓取第 22 个链接: http://www.zut.edu.cn/…/xwgk.htm
开始抓取第 23 个链接: http://www.zut.edu.cn/…/rcyj.htm
开始抓取第 24 个链接: http://www.zut.edu.cn/…/zsjy1.htm
开始抓取第 25 个链接: http://www.zut.edu.cn/…/wlfw.htm
开始抓取第 26 个链接: http://www.zut.edu.cn/xxjj.htm
开始抓取第 27 个链接: http://www.zut.edu.cn/ywjj.htm
开始抓取第 28 个链接: http://www.zut.edu.cn/xxls.htm
开始抓取第 29 个链接: http://www.zut.edu.cn/xxts.htm
开始抓取第 30 个链接: http://www.zut.edu.cn/xzxx.htm
开始抓取第 31 个链接: http://www.zut.edu.cn/xxxg.htm
开始抓取第 32 个链接: http://www.zut.edu.cn/…/xwgk/xwgkzn.htm
开始抓取第 33 个链接: http://www.zut.edu.cn/…/xwgk/xwgkxx.htm
开始抓取第 34 个链接: http://www.zut.edu.cn/…/hzjl1/zwhzbxxxgsl.htm
开始抓取第 35 个链接: http://www.zut.edu.cn/…/xxgk/xxjj.htm
开始抓取第 36 个链接: http://www.zut.edu.cn/…/xxgk/ywjj.htm
开始抓取第 37 个链接: http://www.zut.edu.cn/…/xxgk/xxls.htm
开始抓取第 38 个链接: http://www.zut.edu.cn/…/xxgk/xxts.htm
开始抓取第 39 个链接: http://www.zut.edu.cn/…/xxgk/xzxx.htm
开始抓取第 40 个链接: http://www.zut.edu.cn/…/xxgk/xxxg.htm
开始抓取第 41 个链接: http://www.zut.edu.cn/xwgkzn.htm
开始抓取第 42 个链接: http://www.zut.edu.cn/xwgkxx.htm
开始抓取第 43 个链接: http://www.zut.edu.cn/zwhzbxxxgsl.htm
词表建立完毕!!

print(all_a[:3])
# 输出:
[<a class="menu0_1_" href="../index.htm"><span class="fontstyle67183"> 学校首页 </span></a>, <a class="menu0_1_" href="../xxgk.htm"><span class="fontstyle67183"> 学校概况 </span></a>, <a class="menu0_1_" href="../xybm1.htm"><span class="fontstyle67183"> 学校部门 </span></a>]

2、索引模块——建立倒排词表:见以上代码!!!!

3、网页排名和搜索模块

# search_engine_use.py
import re, urllib
from urllib import request
from collections import deque
from bs4 import BeautifulSoup
import math, jieba, lxml, sqlite3

jieba.load_userdict('dict1.txt')

conn = sqlite3.connect('viewsdu.db')
c = conn.cursor()
c.execute('select count(*) from doc') # 本身就是个计数函数

N = 1 + c.fetchall()[0][0]
target = input('请输入搜索词:')
seggen = jieba.cut_for_search(target) # 产生关键词列表
score = {}
for word in seggen:
    print('得到查询词:', word)  # 一个一个关键词找
    tf = {}
    c.execute('select list from word where term = ?', (word,))
    result = c.fetchall()
    if len(result)>0:
        doclist = result[0][0]              # 字符串“12 35 35 35 88 88”
        doclist = doclist.split(' ')
        doclist = [int(x) for x in doclist] # ['12','35','35','35','88','88']
        df = len(set(doclist))
        idf = math.log(N/df)
        print('idf: ', idf)
        for num in doclist:
            if num in tf:
                tf[num] = tf[num] + 1
            else:
                tf[num] = 1
        for num in tf:
            if num in score:
                score[num] = score[num] + tf[num] * idf
            else:
                score[num] = tf[num] * idf
sortedlist = sorted(score.items(), key=lambda d:d[1], reverse=True)

cnt = 0
for num, docscore in sortedlist:
    cnt = cnt + 1
    c.execute('select link from doc where id=?', (num,))
    url = c.fetchall()[0][0]
    print(url, '得分:', docscore)
    try:
        response = request.urlopen(url)
        content = response.read().decode('utf-8')
    except:
        print('oops...读取页面出错')
        continue
    
    soup = BeautifulSoup(content, 'lxml')
    title =soup.title
    if title == None:
        print('No title.')
    else:
        title = title.text
        print(title)
    if cnt>20:
        break
if cnt == 0:
    print('无搜索结果')

请输入搜索词:河南省
得到查询词: 河南
idf: 0.6931471805599453
得到查询词: 河南省
idf: 0.6931471805599453
http://www.zut.edu.cn 得分: 1.3862943611198906
中原工学院
http://www.zut.edu.cn/index.htm 得分: 1.3862943611198906
中原工学院
http://www.zut.edu.cn/xxgk.htm 得分: 1.3862943611198906
学校概况-中原工学院
http://www.zut.edu.cn/xwgk.htm 得分: 1.3862943611198906
校务公开-中原工学院
http://www.zut.edu.cn/rcyj.htm 得分: 1.3862943611198906
人才引进-中原工学院
http://www.zut.edu.cn/zsjy1.htm 得分: 1.3862943611198906
招生就业-中原工学院
http://www.zut.edu.cn/xxgk/xxjj.htm 得分: 1.3862943611198906
学校简介-中原工学院
http://www.zut.edu.cn/xwgk/xwgkzn.htm 得分: 1.3862943611198906
校务公开指南-中原工学院
http://www.zut.edu.cn/xwgk/xwgkxx.htm 得分: 1.3862943611198906
校务公开信息-中原工学院

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值