目标说明

利用scrapy抓取中新网新闻,关于自然灾害滑坡的全部国内新闻;要求主题为滑坡类新闻,包含灾害造成的经济损失等相关内容,并结合textrank算法,得到每篇新闻的关键词,便于后续文本挖掘分析。

网站分析

目标网站:http://sou.chinanews.com/advSearch.do

结合中新搜索平台的高级搜索的特点,搜索关键词设置为:滑坡 经济损失(以空格隔开),设置分类频道为国内,排序方式按照相关度。得到所有检索到的新闻如下:

共1000多条数据。

分析网站特点发现,给请求为异步加载,通过抓包工具Fiddler得到:

分析:

  POST提交,每次提交目标的url为:http://sou.chinanews.com/search.do

  提交参数如上所示,其中q表示关键词(抓包测试时只输入了一个关键词);

  ps表示每次显示的调试,adv=1表示高级搜索;day1,day2表示搜索时间,默认不写表示全部时间,channel=gn表示国内;

  继续点击下一页,通过对照得到一个新的参数:start,其中当start=0时,默认省略,表示第一页,每次下一页都增加10(设置的页面显示10)

  分析得到,每次点击下一页都是一个POST提交,参数相同,不同的是start

代码逻辑

使用命令:scrapy start project NewsChina创建项目,编写items.py文件,明确抓取字段(常用套路,第一步都是明确抓取字段)。这里只抓取标题和正文。常规操作:添加数据来源和抓取时间信息。

  1. # -*- coding: utf-8 -*-
  2.  
  3. # Define here the models for your scraped items
  4. #
  5. # See documentation in:
  6. # https://doc.scrapy.org/en/latest/topics/items.html
  7.  
  8. import scrapy
  9.  
  10. class NewschinaItem(scrapy.Item):
  11. # define the fields for your item here like:
  12. # name = scrapy.Field()
  13.  
  14. # 数据来源
  15. source = scrapy.Field()
  16. # 抓取时间
  17. utc_time = scrapy.Field()
  18. # 新闻标题
  19. title = scrapy.Field()
  20. # 新闻内容
  21. content = scrapy.Field()
  22. # 关键词
  23. keywords = scrapy.Field()

明确抓取字段后,使用命令:scrapy genspider newsChina 生成爬虫,开始编写爬虫逻辑,结合抓取网站的特点,做以下操作:

针对该网站的反爬措施,添加请求延迟、重试次数等待配置;

通过修改POST请求的time_scope字段,得到每一页数据,并解析数据中详情页的链接,然后对详情页链接请求,解析待抓取数据;

至于循环抓取和终止循环条件,结合实际网站各有不同,在代码中已有说明。

  1. # -*- coding: utf-8 -*-
  2. import re
  3. import scrapy
  4. from NewsChina.items import NewschinaItem
  5.  
  6. class NewschinaSpider(scrapy.Spider):
  7. name = 'newsChina'
  8. # allowed_domains = ['sou.chinanews.com']
  9. # start_urls = ['http://http://sou.chinanews.com/']
  10.  
  11. #爬虫设置
  12. # handle_httpstatus_list = [403] # 403错误时抛出异常
  13. custom_settings = {
  14. "DOWNLOAD_DELAY": 2,
  15. "RETRY_ENABLED": True,
  16. }
  17.  
  18. page = 0
  19. # 提交参数
  20. formdata = {
  21. 'field': 'content',
  22. 'q': '滑坡 经济损失',
  23. 'ps': '',
  24. 'start': '{}'.format(page * 10),
  25. 'adv': '',
  26. 'time_scope': '',
  27. 'day1': '',
  28. 'day2': '',
  29. 'channel': 'gn',
  30. 'creator': '',
  31. 'sort': '_score'
  32. }
  33. # 提交url
  34. url = 'http://sou.chinanews.com/search.do'
  35.  
  36. def start_requests(self):
  37.  
  38. yield scrapy.FormRequest(
  39. url=self.url,
  40. formdata=self.formdata,
  41. callback=self.parse
  42. )
  43.  
  44. def parse(self, response):
  45. try:
  46. last_page = response.xpath('//div[@id="pagediv"]/span/text()').extract()[-1]
  47. # 匹配到尾页退出迭代
  48. if last_page is '尾页':
  49. return
  50. except:
  51. # 当匹配不到last_page时,说明已经爬取所有页面,xpath匹配失败
  52. # 抛出异常,这就是我们的循环终止条件
  53. # print("last_page:", response.url)
  54. return
  55.  
  56. link_list = response.xpath('//div[@id="news_list"]/table//tr/td/ul/li/a/@href').extract()
  57. for link in link_list:
  58. if link:
  59. item = NewschinaItem()
  60. # 访问详情页
  61. yield scrapy.Request(link, callback=self.parse_detail, meta={'item': item})
  62.  
  63. # 循环调用,访问下一页
  64. self.page += 1
  65.  
  66. # 下一页的开始,修改该参数得到新数据
  67. self.formdata['start'] = '{}'.format(self.page * 10)
  68. yield scrapy.FormRequest(
  69. url=self.url,
  70. formdata=self.formdata,
  71. callback=self.parse
  72. )
  73.  
  74. # 从详情页中解析数据
  75. def parse_detail(self, response):
  76. """
  77. 分析发现,中新网年份不同,所以网页的表现形式不同,
  78. 由于抓取的是所有的数据,因此同一个xpath可能只能匹配到部分的内容;
  79. 经过反复测试发现提取规则只有如下几条。提取标题有两套规则
  80. 提取正文有6套规则。
  81. :param response:
  82. :return:
  83. """
  84. item = response.meta['item']
  85.  
  86. # 提取标题信息
  87. if response.xpath('//h1/text()'):
  88. item['title'] = response.xpath('//h1/text()').extract_first().strip()
  89. elif response.xpath('//title/text()'):
  90. item['title'] = response.xpath('//title/text()').extract_first().strip()
  91. else:
  92. print('title:', response.url)
  93.  
  94. # 提取正文信息
  95. try:
  96. if response.xpath('//div[@id="ad0"]'):
  97. item['content'] = response.xpath('//div[@id="ad0"]').xpath('string(.)').extract_first().strip()
  98. elif response.xpath('//div[@class="left_zw"]'):
  99. item['content'] = response.xpath('//div[@class="left_zw"]').xpath('string(.)').extract_first().strip()
  100. elif response.xpath('//font[@id="Zoom"]'):
  101. item['content'] = response.xpath('//font[@id="Zoom"]').xpath('string(.)').extract_first().strip()
  102. elif response.xpath('//div[@id="qb"]'):
  103. item['content'] = response.xpath('//div[@id="qb"]').xpath('string(.)').extract_first().strip()
  104. elif response.xpath('//div[@class="video_con1_text_top"]/p'):
  105. item['content'] = response.xpath('//div[@class="video_con1_text_top"]/p').xpath('string(.)').extract_first().strip()
  106. else:
  107. print('content:', response.url)
  108. except:
  109. # 测试发现中新网有一个网页的链接是空的,因此提前不到正文,做异常处理
  110. print(response.url)
  111. item['content'] = ''
  112.  
  113. yield item

编写中间件,添加随机头信息:

  1. # -*- coding: utf-8 -*-
  2.  
  3. # Define here the models for your spider middleware
  4. #
  5. # See documentation in:
  6. # https://doc.scrapy.org/en/latest/topics/spider-middleware.html
  7. import random
  8. from NewsChina.settings import USER_AGENTS as ua
  9.  
  10. class NewsChinaSpiderMiddleware(object):
  11.  
  12. def process_request(self, request, spider):
  13. """
  14. 给每一个请求随机分配一个代理
  15. :param request:
  16. :param spider:
  17. :return:
  18. """
  19. user_agent = random.choice(ua)
  20. request.headers['User-Agent'] = user_agent

编写数据保存逻辑:

结合python的jieba模块的textrank算法,实现新闻的关键词抽取,并保存到excel或数据库中

  1. # -*- coding: utf-8 -*-
  2.  
  3. # Define your item pipelines here
  4. #
  5. # Don't forget to add your pipeline to the ITEM_PIPELINES setting
  6. # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
  7. from datetime import datetime
  8. from jieba import analyse
  9. from openpyxl import Workbook
  10. import pymysql
  11.  
  12. class KeyswordPipeline(object):
  13. """
  14. 添加数据来源及抓取时间;
  15. 结合textrank算法,抽取新闻中最重要的5个词,作为关键词
  16. """
  17. def process_item(self, item, spider):
  18.  
  19. # 数据来源
  20. item['source'] = spider.name
  21. # 抓取时间
  22. item['utc_time'] = str(datetime.utcnow())
  23.  
  24. content = item['content']
  25. keywords = ' '.join(analyse.textrank(content, topK=5))
  26.  
  27. # 关键词
  28. item['keywords'] = keywords
  29.  
  30. return item
  31.  
  32. class NewsChinaExcelPipeline(object):
  33. """
  34. 数据保存
  35. """
  36. def __init__(self):
  37. self.wb = Workbook()
  38. self.ws = self.wb.active
  39. self.ws.append(['标题', '关键词', '正文', '数据来源', '抓取时间'])
  40.  
  41. def process_item(self, item, spider):
  42.  
  43. data = [item['title'], item['keywords'], item['content'], item['source'], item['utc_time']]
  44.  
  45. self.ws.append(data)
  46. self.wb.save('./news.xls')
  47.  
  48. return item
  49.  
  50. # class NewschinaPipeline(object):
  51. # def __init__(self):
  52. # self.conn = pymysql.connect(
  53. # host='.......',
  54. # port=3306,
  55. # database='news_China',
  56. # user='z',
  57. # password='136833',
  58. # charset='utf8'
  59. # )
  60. # # 实例一个游标
  61. # self.cursor = self.conn.cursor()
  62. #
  63. # def process_item(self, item, spider):
  64. # sql = """
  65. # insert into ChinaNews(ID, 标题, 关键词, 正文, 数据来源, 抓取时间)
  66. # values (%s, %s, %s, %s, %s, %s);"""
  67. #
  68. # values = [
  69. # item['title'],
  70. # item['keywords'],
  71. # item['content'],
  72. #
  73. # item['source'],
  74. # item['utc_time']
  75. # ]
  76. #
  77. # self.cursor.execute(sql, values)
  78. # self.conn.commit()
  79. #
  80. # return item
  81. #
  82. # def close_spider(self, spider):
  83. # self.cursor.close()
  84. # self.conn.close()

运行结果

完成代码

参见:https://github.com/zInPython/NewsChina

scrapy抓取中国新闻网新闻的更多相关文章

  1. scrapy抓取学院新闻报告

    抓取四川大学公共管理学院官网(http://ggglxy.scu.edu.cn)所有的新闻咨询. 实验流程 1.确定抓取目标.2.制定抓取规则.3.'编写/调试'抓取规则.4.获得抓取数据 1.确定抓 ...

  2. scrapy抓取豆瓣电影相关数据

    1. 任务分析及说明 目标网站:https://movie.douban.com/tag/#/ 抓取豆瓣电影上,中国大陆地区,相关电影数据约1000条:数据包括:电影名称.导演.主演.评分.电影类型. ...

  3. 通过Scrapy抓取QQ空间

    毕业设计题目就是用Scrapy抓取QQ空间的数据,最近毕业设计弄完了,来总结以下: 首先是模拟登录的问题: 由于Tencent对模拟登录比较讨厌,各个防备,而本人能力有限,所以做的最简单的,手动登录后 ...

  4. python scrapy 抓取脚本之家文章(scrapy 入门使用简介)

    老早之前就听说过python的scrapy.这是一个分布式爬虫的框架,可以让你轻松写出高性能的分布式异步爬虫.使用框架的最大好处当然就是不同重复造轮子了,因为有很多东西框架当中都有了,直接拿过来使用就 ...

  5. scrapy抓取淘宝女郎

    scrapy抓取淘宝女郎 准备工作 首先在淘宝女郎的首页这里查看,当然想要爬取更多的话,当然这里要查看翻页的url,不过这操蛋的地方就是这里的翻页是使用javascript加载的,这个就有点尴尬了,找 ...

  6. scrapy抓取拉勾网职位信息(一)——scrapy初识及lagou爬虫项目建立

    本次以scrapy抓取拉勾网职位信息作为scrapy学习的一个实战演练 python版本:3.7.1 框架:scrapy(pip直接安装可能会报错,如果是vc++环境不满足,建议直接安装一个visua ...

  7. scrapy抓取的中文结果乱码解决办法

    使用scrapy抓取的结果,中文默认是Unicode,无法显示中文. 中文默认是Unicode,如: \u5317\u4eac\u5927\u5b66 在setting文件中设置: FEED_EXPO ...

  8. 分布式爬虫:使用Scrapy抓取数据

    分布式爬虫:使用Scrapy抓取数据 Scrapy是Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘. ...

  9. 解决Scrapy抓取中文网页保存为json文件时中文不显示而是显示unicode的问题

    注意:此方法跟之前保存成json文件的写法有少许不同之处,注意区分 情境再现: 使用scrapy抓取中文网页,得到的数据类型是unicode,在控制台输出的话也是显示unicode,如下所示 {'au ...

随机推荐

  1. Java多线程编程(一)Java多线程技能

    一.进程和多线程的概念以及线程的优点 打开Windo任务管理器可以看到很多正在运行着的exe程序,完全可以将运行在内存中的exe文件理解成进程,进程是受操作系统管理的基本运行单元. 线程可以理解成在进 ...

  2. redis 基本类型和命令(一)

    一.Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). (1) string类型是Redis最基本的数 ...

  3. linux(CentOS release 6.5)环境搭建svn

    正文之前,说几句关于svn和git的闲话. 之前用的版本控制工具主要都是svn,随着时间的推移,git以其强大灵活的分支管理功能受到大众喜爱.尤其是多人同时开发时同一项目,且不同部分功能时,git的分 ...

  4. 学习笔记42_SpringMVC

    SpringMVC中,Global.axas发生变化,其中 1.原来是 public class MvcApplication:System.web.HttpApplication 现在是 publi ...

  5. golang 包依赖管理 godep 使用

    介绍: godep是解决包依赖的管理工具,目前最主流的一种,原理是扫描记录版本控制的信息,并在go命令前加壳来做到依赖管理. 1.安装: go get github.com/tools/godep 2 ...

  6. if __name__ == "__main__" 的作用

    作用:当模块被直接运行时,以下代码块将被运行,当模块是被导入时,代码块不被运行. 例子: # file one.py def func(): print("func() in one.py& ...

  7. [考试反思]0907NOIP模拟测试39:角落

    题比较简单,但是做的非常烂. T1是个愚蠢的找规律组合数快速幂,数组开小了(看错数据范围) T2题目保证联通没看见,hack掉了正解. T3也挺蠢的,但是打乱了,思路不是很清晰导致丢了50分. 只能说 ...

  8. [考试反思]阶段性总结:NOIP模拟测试7~13

    苟且Rank#1.第二次分机房结束. 得到了喘息一会的权利. 在最后两场考试中大脸skyh慷慨舍弃264分让出Rank#1的故事也十分感人 然而还是有很多东西值得思考. 虽说是反思,但是还是有一些地方 ...

  9. CSS汇总之CSS选择器

    要使用css对HTML页面中的元素实现一对一,一对多或者多对一的控制,这就需要用到CSS选择器. 一.通配符选择器 语法:*{ } 说明:通配符选择器可以选择页面上所有的html标签(包括body,h ...

  10. Python - selenium自动化-Chrome(headless)

    什么是 Headless Chrome Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序.相比于现代浏览 ...