最近一直在爬新闻,对于新闻爬取的套路还是比较熟悉的。一个群友发布了一个爬文章入word的任务,我果断接单,自我挑战一下,更何况完成任务还有赏金,哈哈。

任务大概是这样的,有一个文章列表【http://www.shui5.cn/article/Bulletin/】,大约7W的量,每篇文章保存到一个word文件中。

任务比较清晰,观察一下文章内容,发现所有的文章格式都是一致的,这样就比较简单了,只要能爬出一篇文章就搞定了。

但是,现在有一个问题需要优先解决,就是如何用python操作word文档。

第一步:何用python操作word文档

首先明白一点,手动创建的以“.doc”或“.docx”结尾的文件并不是真正的word文件,以word文件的方式打开时会报错的。

网上给的方法是使用python-docx扩展包。

安装:

pip install python-docx

使用方法:

 #引入docx扩展包
import docx #创建document 对象
document = docx.Document() #添加标题,第二个参数是标题的等级
document.add_heading(title, 1) #添加段落
document.add_paragraph(content) #保存成一个docx文件
document.save(file_name)

我的需求是往word文档里添加标题和正文,没有图片,也不需要调整格式,所以有这几个接口就够用了。如果想查看更多接口,可以去这里https://python-docx.readthedocs.io/en/latest/index.html

第二步:爬一篇文章试试

首先分析一下页面结构,页面包含顶部导航、中间的文章列表和底部的分页。

顶部导航是爬虫入口,从这12个分类开始,进入每个分类的文章列表

中部是文章列表,底部是分页,先爬当前页的文章列表,然后从底部进入下一页的文章列表,直到没有下一页的时候。

也可以爬完第一页的时候,分析后续页面的链接特征,同时爬剩下的所有页。但是这样会造成爬虫并发过大,导致一些不可预知的问题。

我采用的是第一种,每次爬一页,然后从“下一页”的链接进入下一个文章列表,直到结束。

先把最后的代码贴出来,再逐一说明

 #!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2018-04-18 09:42:32
# Project: 1 from pyspider.libs.base_handler import *
import re, docx URL_ARR = {
'http://www.shui5.cn/article/FaGuiJieDu/'
} class Handler(BaseHandler):
crawl_config = {
} @every(minutes=24 * 60)
def on_start(self): #爬虫入口
for each in URL_ARR:
self.crawl(each, callback=self.news_list) #新闻列表
@config(age=60 * 60)
def news_list(self, response):
#当页新闻列表
if response.doc('.arcList').html():
for each in response.doc('.arcList a').items():
if re.match("http://www.shui5.cn/article/.", each.attr.href, re.U):
self.crawl(each.attr.href, callback=self.news_content) #下一页
next_page_index = response.doc('.pagelist.clearfix a').length - 2
if u"下一页" in response.doc('.pagelist.clearfix a').eq(next_page_index).text():
url = response.doc('.pagelist.clearfix a').eq(total_pages).attr.href
self.crawl(url, callback=self.news_list) #新闻内容
@config(priority=2)
@catch_status_code_error
def news_content(self, response): if response.doc('.arcContent').html():
document = docx.Document()
title = response.doc('.articleTitle h1').text().replace('/', u'、')
document.add_heading(title, 1)
for a in response.doc('.articleDes, .arcContent table p').items():
document.add_paragraph(a.text())
file_name = (u'/pyspider/htmlfiles/wordFile/1/' + title + '.docx').encode('gbk')
document.save(file_name)
else:
return {}

特别说明

第46行代码

title = response.doc('.articleTitle h1').text().replace('/', u'、')

这是取文章标题的逻辑,最后有个replace的操作,是因为有的文章标题中有“/”,document.save的时候,会把这个斜杠解析成一级目录,导致保存乱套,所以把标题中的斜杠都替换成顿号了。unicode编码表中没有中文顿号的符号,所以前面加u。

还有50行代码

file_name = (u'/pyspider/htmlfiles/wordFile/1/' + title + '.docx').encode('gbk')

这句是拼word文件名称和保存路径的操作,最后有个encode操作,即编码成gbk,此处是有特殊含义的

我们都知道,在python中默认的编码格式是unicode,而unicode能编码的字符比较少,遇到汉字就无能为力了,只能绕道走,通过把汉字编码成别的编码格式,然后储存第三方编码后的结果。具体的这种第三方编码选谁呢,我在代码第二行已经定义了,即utf-8。所以最后保存的word文件的名称和内容都是utf-8编码的。我的linux的默认编码格式是utf-8(你可以echo $LANG查看一下,或者通过修改/etc/profile文件来修改),所以在linux下是没啥问题的。关键是传输到windows下就出问题了。windows系统默认编码格式是gbk,而word内容的编码是utf-8,所以最后就看到word文件名称乱码而内容正常显示。这也就是我为什么在拼出word文档的标题后,要将它转码为gbk的原因了。

pyspider爬一批文章保存到word中的更多相关文章

  1. python爬取数据保存到Excel中

    # -*- conding:utf-8 -*- # 1.两页的内容 # 2.抓取每页title和URL # 3.根据title创建文件,发送URL请求,提取数据 import requests fro ...

  2. 将爬取的数据保存到mysql中

    为了把数据保存到mysql费了很多周折,早上再来折腾,终于折腾好了 安装数据库 1.pip install pymysql(根据版本来装) 2.创建数据 打开终端 键入mysql -u root -p ...

  3. PHP操作:将数据库中的数据保存到Word、Excel中。

    1.首先要把word.excel表放到文件的根目录下 2.定义了一个word类 <?php class word { function start() { ob_start(); ob_star ...

  4. 1.scrapy爬取的数据保存到es中

    先建立es的mapping,也就是建立在es中建立一个空的Index,代码如下:执行后就会在es建lagou 这个index.     from datetime import datetime fr ...

  5. ffmpeg从AVFrame取出yuv数据到保存到char*中

    ffmpeg从AVFrame取出yuv数据到保存到char*中   很多人一直不知道怎么利用ffmpeg从AVFrame取出yuv数据到保存到char*中,下面代码将yuv420p和yuv422p的数 ...

  6. 将数字n转换为字符串并保存到s中

    将数字n转换为字符串并保存到s中 参考 C程序设计语言 #include <stdio.h> #include <string.h> //reverse函数: 倒置字符串s中各 ...

  7. Android把图片保存到SQLite中

    1.bitmap保存到SQLite 中 数据格式:Blob db.execSQL("Create table " + TABLE_NAME + "( _id INTEGE ...

  8. c# 抓取和解析网页,并将table数据保存到datatable中(其他格式也可以,自己去修改)

    使用HtmlAgilityPack 基础请参考这篇博客:https://www.cnblogs.com/fishyues/p/10232822.html 下面是根据抓取的页面string 来解析并保存 ...

  9. Flask实战第43天:把图片验证码和短信验证码保存到memcached中

    前面我们已经获取到图片验证码和短信验证码,但是我们还没有把它们保存起来.同样的,我们和之前的邮箱验证码一样,保存到memcached中 编辑commom.vews.py .. from utils i ...

随机推荐

  1. [PHP] 数据结构-循环链表的PHP实现

    1.将单链表中终端结点的指针端由空指针改为指向头结点,单循环链表,循环链表和单链表的主要差异就在于循环的判断条件上原来是判断p->next是否为空,现在则是p->next不等于头结点,则循 ...

  2. Java学习笔记之——Java介绍

    1.Java体系: JavaSE:标准版,其他两个体系的基础 JavaEE:企业版 JavaME:微型版,适用于消费类型的微型设备 2.Java三大特性:封装.继承.多态 3.Java的特点:面向对象 ...

  3. Java文件编译出现 “编码 GBK 的不可映射字符”

    俗话说,温故而知新.本打算用dos回忆一下基础知识,没想到把自己绊倒了. 用Dos,当然就要回归原始,用记事本啦.下面用一个小练习,演示我遇到的绊脚石.之后,解决了简直笑死. 报错: Java文件编译 ...

  4. Java集合之HashSet源码分析

    概述 HashSet是基于HashMap来实现的, 底层采用HashMap的key来保存数据, 借此实现元素不重复, 因此HashSet的实现比较简单, 基本上的都是直接调用底层HashMap的相关方 ...

  5. UED与UCD

    UED User Experience Design(用户体验设计),简称UED.UED是以用户为中心的一种设计手段,以用户需求为目标而进行的设计.设计过程注重以用户为中心,用户体验的概念从开发的最早 ...

  6. 深入研究HTML5实现图片压缩上传

    上篇文章中提到移动端上传图片,我们知道现在流量还是挺贵的,手机的像素是越来越高,拍个照动不动就是好几M,伤不起.虽然客户端可以轻轻松松实现图片压缩再上传,但是我们的应用还可能在浏览器里面打开,怎么办呢 ...

  7. ArcGIS Portal与Adapter安装问题

    1. WIN2008R2 80端口被system占用解决办法 修改注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP右侧的star ...

  8. Visualforce简介

    Visualforce Visualforce是一个和Apex语言相匹配的开发框架.开发者可以使用Visualforce和Apex建立自定义网络应用程序. Visualforce的基本功能类似于前端框 ...

  9. VXLAN技术在数据中心的应用

    1.VXLAN技术可以通过物理交换机实现,也可以通过服务器实现,这两种实现的后台反应的是CT技术,还是IT技术来主导数据中心虚拟网络的发展. 2.物理交换机实现的VXLAN受限于芯片支持的规则,一般情 ...

  10. MySQL 性能优化--优化数据库结构之优化数据类型

    MySQL性能优化--优化数据库结构之优化数据类型   By:授客  QQ:1033553122   优化数字数据(Numeric Data) l   对于唯一ID或其它可用字符串或数字表示的值,选择 ...