[内附完整源码和文档] 基于python的新闻检索系统

Python018

[内附完整源码和文档] 基于python的新闻检索系统,第1张

1 系统介绍

1.1 系统需求

新闻检索系统:定向采集不少于 4 个中文社会新闻网站或频道,实现这些网站新闻信息及评论信息的自动爬取、抽取、索引和检索。本项目未使用 lucene,Goose 等成熟开源框架。

1.2 系统思路与框架

本系统总体的实现思路如图 1 所示:

一个完整的搜索系统主要的步骤是:

对新闻网页进行爬虫得到语料库

抽取新闻的主体内容,得到结构化的 xml 数据

内存式单遍扫描索引构建方法构建倒排索引,供检索模块使用

用户输入查询,得到相关文档返回给用户

2 设计方案

2.1 新闻爬取

2.1.1 算法简述

该模块针对搜狐,网易,腾讯三大主流新闻网站及官方的参考消息网站进行了新闻获取。并基于其网站结构,设计了不同的爬取模式。由于网站架构两两相似,以下选取两种类型的典型代表进行介绍:

(1)搜狐新闻

搜狐新闻除正常主页外,存在隐藏的列表式新闻页 , 如 http://news.sohu.com/1/0903/62/subject212846206.shtml 。

(2)网易新闻

可以将网易新闻及腾讯新闻归结为一般类型的新闻主页,我们采用了自新闻主页开始的广度优先的递归爬取策略。注意到新闻的正文页往往是静态网页.html,因此,我们将网页中出现的所有以.html 结尾的网页的 URL 均记录下来,在爬取到一定量时,进行一次去重。

对于一些不是新闻的错分网页,容错处理即通过检查新闻正文标签

时会被剔除。

新闻正文页中我们重点关注内容,时间,评论获取。

2.1.2 创新点

实现了对新闻网页动态加载的评论进行爬取,如搜狐新闻评论爬取

未借助开源新闻爬取工具,自己实现了对新闻标题,正文,时间,评论内容,评论数目的高效爬取

2.2 索引构建

分词,我们借助开源的 jieba 中文分词组件来完成,jieba 分词能够将一个中文句子切成一个个词项,这样就可以统计 tf, df 了

去停用词,去停词的步骤在 jieba 分词之后完成

倒排记录表存储,词典用 B-树或 hash 存储,倒排记录表用邻接链表存储方式,这样能大大减少存储空间

倒排索引构建算法使用内存式单遍扫描索引构建方法(SPIMI),就是依次对每篇新闻进行分词,如果出现新的词项则插入到词典中,否则将该文档的信息追加到词项对应的倒排记录表中。

2.3 检索模块

2.3.1 检索模式

(1)关键词检索

查询即根据用户输入的关键字,返回其相应的新闻。首先根据用户的查询进行 jieba 分词,记录分词后词项的数量以字典形式进行存储。

完整的源码和详细的文档,上传到了 WRITE-BUG技术共享平台 上,需要的请自取:

https://www.write-bug.com/article/3122.html

需求:

从门户网站爬取新闻,将新闻标题,作者,时间,内容保存到本地txt中。

用到的python模块: import re  # 正则表达式

import bs4  # Beautiful Soup 4 解析模块

import urllib2  # 网络访问模块

import News   #自己定义的新闻结构

import codecs  #解决编码问题的关键 ,使用codecs.open打开文件

import sys   #1解决不同页面编码问题

其中bs4需要自己装一下,安装方法可以参考:Windows命令行下pip安装python whl包

程序:

#coding=utf-8

import re  # 正则表达式

import bs4  # Beautiful Soup 4 解析模块

import urllib2  # 网络访问模块

import News   #自己定义的新闻结构

import codecs  #解决编码问题的关键 ,使用codecs.open打开文件

import sys   #1解决不同页面编码问题

reload(sys)                         # 2

sys.setdefaultencoding('utf-8')     # 3

# 从首页获取所有链接

def GetAllUrl(home):

    html = urllib2.urlopen(home).read().decode('utf8')

    soup = bs4.BeautifulSoup(html, 'html.parser')

    pattern = 'http://\w+\.baijia\.baidu\.com/article/\w+'

    links = soup.find_all('a', href=re.compile(pattern))

    for link in links:

        url_set.add(link['href'])

def GetNews(url):

    global NewsCount,MaxNewsCount  #全局记录新闻数量

    while len(url_set) != 0:

        try:

            # 获取链接

            url = url_set.pop()

            url_old.add(url)

            # 获取代码

            html = urllib2.urlopen(url).read().decode('utf8')

            # 解析

            soup = bs4.BeautifulSoup(html, 'html.parser')

            pattern = 'http://\w+\.baijia\.baidu\.com/article/\w+'  # 链接匹配规则

            links = soup.find_all('a', href=re.compile(pattern))

            # 获取URL

            for link in links:

                if link['href'] not in url_old:

                    url_set.add(link['href'])

                    # 获取信息

                    article = News.News()

                    article.url = url  # URL信息

                    page = soup.find('div', {'id': 'page'})

                    article.title = page.find('h1').get_text()  # 标题信息

                    info = page.find('div', {'class': 'article-info'})

                    article.author = info.find('a', {'class': 'name'}).get_text()  # 作者信息

                    article.date = info.find('span', {'class': 'time'}).get_text()  # 日期信息

                    article.about = page.find('blockquote').get_text()

                    pnode = page.find('div', {'class': 'article-detail'}).find_all('p')

                    article.content = ''

                    for node in pnode:  # 获取文章段落

                        article.content += node.get_text() + '\n'  # 追加段落信息

                    SaveNews(article)

                    print NewsCount

                    break

        except Exception as e:

            print(e)

            continue

        else:

            print(article.title)

            NewsCount+=1

        finally:

            # 判断数据是否收集完成

            if NewsCount == MaxNewsCount:

                break

def SaveNews(Object):

    file.write("【"+Object.title+"】"+"\t")

    file.write(Object.author+"\t"+Object.date+"\n")

    file.write(Object.content+"\n"+"\n")

url_set = set()  # url集合

url_old = set()  # 爬过的url集合

NewsCount = 0

MaxNewsCount=3

home = 'http://baijia.baidu.com/'  # 起始位置

GetAllUrl(home)

file=codecs.open("D:\\test.txt","a+") #文件操作

for url in url_set:

    GetNews(url)

    # 判断数据是否收集完成

    if NewsCount == MaxNewsCount:

        break

file.close()

新闻文章结构

#coding: utf-8

# 文章类定义

class News(object):

    def __init__(self):

        self.url = None

        self.title = None

        self.author = None

        self.date = None

        self.about = None

        self.content = None

对爬取的文章数量就行统计。