欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python网络爬虫和文档内容提取

程序员文章站 2023-11-24 12:09:10
网络爬虫和文档内容提取一、实验内容1.设计一个网页爬虫程序或者配置运行开源的网络爬虫进行网页抓取,可以选择爬取新闻网站和电子商务网站的产品评论。不同主题类别的网页存放在不同的目录下2.掌握网页的标签结构特点以及内容提取原理,设计和实现网页内容提取程序文档内容提取分为2个小题目,任选一个做。a.提取新闻网页的标题,正文,发表时间。b.提取某产品的每条产品评论内容,发表时间。二、实验环境实验环境:Python3.6.2,IDE:Pycharm 2019.1.3三、实验功能requests 库...

网络爬虫和文档内容提取

一、实验内容

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)

六、实验截图

python网络爬虫和文档内容提取
python网络爬虫和文档内容提取python网络爬虫和文档内容提取

本文地址:https://blog.csdn.net/Btbsja/article/details/107081215