网络爬虫和文档内容提取

网络爬虫和文档内容提取

一、实验内容

1.设计一个网页爬虫程序或者配置运行开源的网络爬虫进行网页抓取,可以选择爬取新闻网站和电子商务网站的产品评论。不同主题类别的网页存放在不同的目录下

2.掌握网页的标签结构特点以及内容提取原理,设计和实现网页内容提取程序文档内容提取分为2个小题目,任选一个做。

a.提取新闻网页的标题,正文,发表时间。

b.提取某产品的每条产品评论内容,发表时间。

二、实验环境

实验环境:Python3.6.2,

IDE:Pycharm 2019.1.3

三、实验功能

requests 库主要用来发起网络请求,并接收服务器返回的数据;bs4 库主要用来解析 html 内容,是一个非常简单好用的库;os 库主要用于将数据输出存储到本地文件中。

fetchUrl 函数用于发起网络请求,它可以访问目标 url ,获取目标网页的 html 内容并返回。

这里其实是应该做异常捕获的(我为了简单就省掉了,吐舌头)。因为网络情况比较复杂,可能会因为各种各样的原因而访问失败, r.raise_for_status() 这句代码其实就是在判断是否访问成功的,如果访问失败,返回的状态码不是 200 ,执行到这里时会直接抛出相应的异常。

getPageList 函数,用于爬取当天报纸的各版面的链接,将其保存为一个数组,并返回。

getPageList 函数,用于爬取当天报纸的某一版面的所有文章的链接,将其保存为一个数组,并返回。

getContent 函数,用于访问文章内容页,爬取文章的标题和正文,并返回。

saveFile 函数用于将文章内容保存到本地的指定文件夹中。

download_rmrb 函数是需求中要求的主函数,可以根据 year,month,day 参数,下载该天的全部报纸文章内容,并按照规则保存在指定的路径 destdir 下。

四、实验策略

1. URL 组成结构

人民日报网站的 URL 的结构还是比较直观的,基本上什么重要的参数,比如日期,版面号,文章编号什么的,都在 URL 中有所体现,构成的规则也很简单,像这样

版面目录:http://paper.people.com.cn/rmrb/html/2019-05/06/nbs.D110000renmrb_01.htm

文章内容:http://paper.people.com.cn/rmrb/html/2019-05/06/nw.D110000renmrb_20190506_5-01.htm

在版面目录的链接中,"/2019-05/06/" 表示日期,后面的 “_01” 表示这是第一版面的链接。

在文章内容的链接中,"/2019-05/06/" 表示日期,后面的 “_20190506_5_01” 表示这是 2019 年 5 月 6 日报纸的第 1 版第 5 篇文章

值得注意的是,在日期的 “月” 和 “日” 以及 “版面号” 的数字,若小于 10,需在前面补 “0” ,而文章的篇号则不必。

了解到这个之后,我们可以按照这个规则,构造出任意一天报纸中人一个版面的链接,以及任意一篇文章的链接。

如:2018 年 6 月 5 日第 4 版的目录链接为:

http://paper.people.com.cn/rmrb/html/2019-05/06/nbs.D110000renmrb_01.htm

2018 年 6 月 1 日第 2 版第 3 篇文章的链接为:

http://paper.people.com.cn/rmrb/html/2018-06/01/nw.D110000renmrb_20180601_3-02.htm

点击访问,发现果然是这样。至此,网站的 URL 组成结构分析完成。

2.分析网页 HTML 结构

在 URL 分析中,我们也发现了,网站的页面跳转是通过 URL 的改变完成的,不涉及到诸如 Ajax 这样的动态加载方法。也就是说,它的所有数据是一开始就加载好的,我们只需要去 html 中提取相应得数据即可。

好了,言归正传,我们来分析一下我们的目标网站。按 F12 召唤出开发者工具(点击图中 1 处的小箭头,然后点击网页中的内容,可以在 html 源码中快速找到相应的位置)。

我们可以知道,版面目录存放在一个 id = “pageList” 的 div 标签下,class = “right_title1” 或 “right_title2” 的 div 标签中,每一个 div 表示一个版面,而版面的链接就在 id = “pageLink” 的 a 标签中。

使用同样的方法,我们可以知道,文章目录存放在一个 id = “titleList” 的 div 标签下的 ul 标签中,其中每一个 li 标签表示一篇文章,而文章的链接就在 li 标签下的 a 标签中。

进入文章内容页面之后,我们可以知道,文章标题存放在 h1 ,h2 ,h3 标签中(有的文章标题只用到了 h1 标签,而有的文章有副标题可能会用到 h2 或 h3 标签), 正文部分存放在 id = “ozoom” 的 div 标签下的 p 标签里。

至此,目标网站的 HTML 页面分析完成。

3. 制定爬取策略

通过分析 URL 组成结构以及目标网站的 HTML 结构,我们已经完成了爬虫的前期调研工作,接下来需要根据网站的特点制定相应的爬取策略,然后评估每种方法的优劣和难易程度,最终选择一种最佳方案,进行编码实现。

第一遍,先爬取版面目录,将每一个版面的链接保存下来;第二遍,依次访问每一个版面的链接,将该版面的文章链接保存下来;第三遍,依次访问每一个文章链接,将文章的标题和正文保存到本地。

五、实验代码

import requests
import bs4
import os

#URL
def fetchUrl(url):
       
    headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
    }
    
    r = requests.get(url,headers=headers)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    return r.text
#
def getPageList(year, month, day):
   
    url = 'http://paper.people.com.cn/rmrb/html/' + year + '-' + month + '/' + day + '/nbs.D110000renmrb_01.htm'
    html = fetchUrl(url)
    bsobj = bs4.BeautifulSoup(html,'html.parser')
    pageList = bsobj.find('div', attrs = {'id': 'pageList'}).ul.find_all('div', attrs = {'class': 'right_title-name'})
    linkList = []
    
    for page in pageList:
        link = page.a["href"]
        url = 'http://paper.people.com.cn/rmrb/html/'  + year + '-' + month + '/' + day + '/' + link
        linkList.append(url)
    
    return linkList
#
def getTitleList(year, month, day, pageUrl):
   
    html = fetchUrl(pageUrl)
    bsobj = bs4.BeautifulSoup(html,'html.parser')
    titleList = bsobj.find('div', attrs = {'id': 'titleList'}).ul.find_all('li')
    linkList = []
    
    for title in titleList:
        tempList = title.find_all('a')
        for temp in tempList:
            link = temp["href"]
            if 'nw.D110000renmrb' in link:
                url = 'http://paper.people.com.cn/rmrb/html/'  + year + '-' + month + '/' + day + '/' + link
                linkList.append(url)
    
    return linkList
#
def getContent(html):
   
    bsobj = bs4.BeautifulSoup(html,'html.parser')
    
    title = bsobj.h3.text + '\n' + bsobj.h1.text + '\n' + bsobj.h2.text + '\n'
    #print(title)
    

    pList = bsobj.find('div', attrs = {'id': 'ozoom'}).find_all('p')
    content = ''
    for p in pList:
        content += p.text + '\n'      
    #print(content)
    

    resp = title + content
    return resp
#本地
def saveFile(content, path, filename):
    
    # 如果没有该文件夹,则自动生成
    if not os.path.exists(path):
        os.makedirs(path)
        
    # 保存文件
    with open(path + filename, 'w', encoding='utf-8') as f:
        f.write(content)
#主函数
def download_rmrb(year, month, day, destdir):
   
    pageList = getPageList(year, month, day)
    for page in pageList:
        titleList = getTitleList(year, month, day, page)
        for url in titleList:
            
            # 获取新闻文章内容
            html = fetchUrl(url)
            content = getContent(html)
            
            # 生成保存的文件路径及文件名
            temp = url.split('_')[2].split('.')[0].split('-')
            pageNo = temp[1]
            titleNo = temp[0] if int(temp[0]) >= 10 else '0' + temp[0]
            path = destdir + '/' + year + month + day + '/'
            fileName = year + month + day + '-' + pageNo + '-' + titleNo + '.txt'
            
            # 保存文件
            saveFile(content, path, fileName)

#入口            
if __name__ == '__main__':
 
    year = "2019"
    month = "06"
    day = "04"
    destdir = "C:/data"
 
    download_rmrb(year, month, day, destdir)
    print("爬取完成:" + year + month + day)

六、实验截图

网络爬虫和文档内容提取_第1张图片
网络爬虫和文档内容提取_第2张图片网络爬虫和文档内容提取_第3张图片

你可能感兴趣的:(Python)