Python使用scrapy爬取阳光热线问政平台过程解析


Posted in Python onAugust 14, 2019

目的:爬取阳光热线问政平台问题反映每个帖子里面的标题、内容、编号和帖子url

CrawlSpider版流程如下:

创建爬虫项目dongguang

scrapy startproject dongguang

设置items.py文件

# -*- coding: utf-8 -*-
import scrapy
class NewdongguanItem(scrapy.Item):
  # define the fields for your item here like:
  # name = scrapy.Field()
  # pass
  # 每页的帖子链接
  url = scrapy.Field()
  # 帖子标题
  title = scrapy.Field()
  # 帖子编号
  number = scrapy.Field()
  # 帖子内容
  content = scrapy.Field()

在spiders目录里面,创建并编写爬虫文件sun.py

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from dongguan.items import DongguanItem
class SunSpider(CrawlSpider):
  name = 'dg'
  allowed_domains = ['wz.sun0769.com']
  start_urls = ['http://wz.sun0769.com/html/top/report.shtml']
  # rules是Rule的集合,每个rule规则同时执行。另外,如果发现web服务器有反爬虫机制如返回一个假的url,则可以使用Rule里面的参数process_links调用一个自编函数来处理url后返回一个真的url
  rules = (
    # 每个url都有一个独一无二的指纹,每个爬虫项目都有一个去重队列
    # Rule里面没有回调函数,则默认对匹配的链接要跟进,就是对匹配的链接在进行请求获取响应后对响应里面匹配的链接继续跟进,只不过没有回调函数对响应数据进行处理
    # Rule(LinkExtractor(allow="page="))如果设置为follow=False,则不会跟进,只显示当前页面匹配的链接。如设置为follow=True,则会对每个匹配的链接发送请求获取响应进而从每个响应里面再次匹配跟进,直至没有。python递归深度默认为不超过1000,否则会报异常
    Rule(LinkExtractor(allow="page=")),

    Rule(LinkExtractor(allow='http://wz.sun0769.com/html/question/\d+/\d+.shtml'),callback='parse_item')

  )

  def parse_item(self, response):
    print(response.url)
    item = DongguanItem()
    item['url'] = response.url
    item['title'] = response.xpath('//div[@class="pagecenter p3"]//strong/text()').extract()[0]
    item['number'] = response.xpath('//div[@class="pagecenter p3"]//strong/text()').extract()[0].split(' ')[-1].split(':')[-1]
     # 对帖子里面有图片的处理,发现没有图片时则没有class="contentext"的div标签,以此作为标准获取帖子内容
    if len(response.xpath('//div[@class="contentext"]')) == 0:
      item['content'] = ''.join(response.xpath('//div[@class="c1 text14_2"]/text()').extract())
    else:
      item['content'] = ''.join(response.xpath('//div[@class="contentext"]/text()').extract())
    yield item

编写管道pipelines.py文件

# -*- coding: utf-8 -*-
import json
class DongguanPipeline(object):
  def __init__(self):
    self.file = open('dongguan.json','w')
  def process_item(self, item, spider):
    content = json.dumps(dict(item),ensure_ascii=False).encode('utf-8') + '\n'
    self.file.write(content)
    return item
  def closespider(self):
    self.file.close()

编写settings.py文件

# -*- coding: utf-8 -*-
BOT_NAME = 'dongguan'
SPIDER_MODULES = ['dongguan.spiders']
NEWSPIDER_MODULE = 'dongguan.spiders'
# log日志文件默认保存在当前目录,下面为日志级别,当大于或等于INFO时将被保存
LOG_FILE = 'dongguan.log'
LOG_LEVEL = 'INFO'
# 爬取深度设置
# DEPTH_LIMIT = 1
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'dongguan (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
  'dongguan.pipelines.DongguanPipeline': 300,
}

测试运行爬虫,终端执行命令(只要在项目目录内即可)

scrapy crawl dg

Spider版流程如下:

创建爬虫项目newdongguang

scrapy startproject newdongguan

设置items.py文件

# -*- coding: utf-8 -*-
  import scrapy
  class NewdongguanItem(scrapy.Item):
    # 每页的帖子链接
    url = scrapy.Field()
    # 帖子标题
    title = scrapy.Field()
    # 帖子编号
    number = scrapy.Field()
    # 帖子内容
    content = scrapy.Field()

在spiders目录里面,创建并编写爬虫文件newsun.py

# -*- coding: utf-8 -*-
import scrapy
from newdongguan.items import NewdongguanItem
class NewsunSpider(scrapy.Spider):
  name = 'ndg'
  # 设置爬取的域名范围,可写可不写,不写则表示爬取时候不限域名,结果有可能会导致爬虫失控。
  allowed_domains = ['wz.sun0769.com']
  offset = 0
  url = 'http://wz.sun0769.com/index.php/question/report?page=' + str(offset)
  start_urls = [url]
  def parse(self, response):
    link_list = response.xpath("//a[@class='news14']/@href").extract()
    for each in link_list:
      # 对每页的帖子发送请求,获取帖子内容里面指定数据返回给管道文件
      yield scrapy.Request(each,callback=self.deal_link)
    self.offset += 30
    if self.offset <= 124260:
      url = 'http://wz.sun0769.com/index.php/question/report?page=' + str(self.offset)
      # 对指定分页发送请求,响应交给parse函数处理
      yield scrapy.Request(url,callback=self.parse)

  # 从每个分页帖子内容获取数据,返回给管道
  def deal_link(self,response):
    item = NewdongguanItem()
    item['url'] = response.url
    item['title'] = response.xpath("//div[@class='pagecenter p3']//strong[@class='tgray14']/text()").extract()[0]
    item['number'] = response.xpath("//div[@class='pagecenter p3']//strong[@class='tgray14']/text()").extract()[0].split(' ')[-1].split(':')[-1]

    if len(response.xpath("//div[@class='contentext']")) == 0:
      item['content'] = ''.join(response.xpath("//div[@class='c1 text14_2']/text()").extract())
    else:
      item['content'] = ''.join(response.xpath("//div[@class='contentext']/text()").extract())
    yield item

编写管道pipelines.py文件

# -*- coding: utf-8 -*-
import codecs
import json
class NewdongguanPipeline(object):

  def __init__(self):
    # 使用codecs写文件,直接设置文件内容编码格式,省去每次都要对内容进行编码
    self.file = codecs.open('newdongguan.json','w',encoding = 'utf-8')
    # 以前文件写法
    # self.file = open('newdongguan.json','w')

  def process_item(self, item, spider):
    print(item['title'])
    content = json.dumps(dict(item),ensure_ascii=False) + '\n'
    # 以前文件写法
    # self.file.write(content.encode('utf-8'))
    self.file.write(content)
    return item

  def close_spider(self):
    self.file.close()

编写settings.py文件

# -*- coding: utf-8 -*-
BOT_NAME = 'newdongguan'
SPIDER_MODULES = ['newdongguan.spiders']
NEWSPIDER_MODULE = 'newdongguan.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'newdongguan (+http://www.yourdomain.com)'
USER_AGENT = 'User-Agent:Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;'
# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
  'newdongguan.pipelines.NewdongguanPipeline': 300,
}

测试运行爬虫,终端执行命

srapy crawl ndg

备注:markdown语法关于代码块缩进问题,可通过tab键来解决。而简单文本则可以通过回车键来解决,如Spider版流程如下:和1. 创建爬虫项目newdongguang

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python安装第三方库的3种方法
Jun 21 Python
python基础知识小结之集合
Nov 25 Python
Java Web开发过程中登陆模块的验证码的实现方式总结
May 25 Python
详解python进行mp3格式判断
Dec 23 Python
python3中set(集合)的语法总结分享
Mar 24 Python
python微信跳一跳系列之色块轮廓定位棋盘
Feb 26 Python
python高阶爬虫实战分析
Jul 29 Python
Python简易版停车管理系统
Aug 12 Python
Python使用字典实现的简单记事本功能示例
Aug 15 Python
Python 求数组局部最大值的实例
Nov 26 Python
Python暴力破解Mysql数据的示例
Nov 09 Python
使用Python的开发框架Brownie部署以太坊智能合约
May 28 Python
用Python抢火车票的简单小程序实现解析
Aug 14 #Python
Python定时任务随机时间执行的实现方法
Aug 14 #Python
查看Python依赖包及其版本号信息的方法
Aug 13 #Python
使用python实现unix2dos和dos2unix命令的例子
Aug 13 #Python
Python编写带选项的命令行程序方法
Aug 13 #Python
使用python模拟命令行终端的示例
Aug 13 #Python
在macOS上搭建python环境的实现方法
Aug 13 #Python
You might like
php&amp;java(一)
2006/10/09 PHP
模板引擎正则表达式调试小技巧
2011/07/20 PHP
用PHP编写和读取XML的几种方式
2013/01/12 PHP
基于PHP Socket配置以及实例的详细介绍
2013/06/13 PHP
PHP 转义使用详解
2013/07/15 PHP
PHP中异常处理的一些方法整理
2015/07/03 PHP
PHP水印类,支持添加图片、文字、填充颜色区域的实现
2017/02/04 PHP
使用ThinkPHP生成缩略图及显示
2017/04/27 PHP
php+ajax实现异步上传文件或图片功能
2017/07/18 PHP
php实现的统计字数函数定义与使用示例
2017/07/26 PHP
PHP实现redis限制单ip、单用户的访问次数功能示例
2018/06/16 PHP
Laravel框架执行原生SQL语句及使用paginate分页的方法
2018/08/17 PHP
php和js实现根据子网掩码和ip计算子网功能示例
2019/11/09 PHP
canvas简单快速的实现知乎登录页背景效果
2017/05/08 Javascript
浅谈angular4 ng-content 中隐藏的内容
2017/08/18 Javascript
jquery 给动态生成的标签绑定事件的几种方法总结
2018/02/24 jQuery
基于vuex实现购物车功能
2021/01/10 Vue.js
[03:39]2015国际邀请赛主赛事首日精彩回顾
2015/08/05 DOTA
[46:32]Fnatic vs OG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python中为什么要用self探讨
2015/04/14 Python
Python 模拟员工信息数据库操作的实例
2017/10/23 Python
tensorflow建立一个简单的神经网络的方法
2018/02/10 Python
python实现比较文件内容异同
2018/06/22 Python
python设置环境变量的原因和方法
2019/06/24 Python
Python中低维数组填充高维数组的实现
2019/12/02 Python
在pytorch中实现只让指定变量向后传播梯度
2020/02/29 Python
Django实现将一个字典传到前端显示出来
2020/04/03 Python
HomeAway的巴西品牌:Alugue Temporada
2018/04/10 全球购物
Interhome丹麦:在线预订度假屋和公寓
2019/07/18 全球购物
县优秀教师事迹材料
2014/01/31 职场文书
六查六看自检自查剖析材料
2014/10/14 职场文书
关于颐和园的导游词
2015/01/30 职场文书
常住证明范本
2015/06/23 职场文书
施工现场安全管理制度
2015/08/05 职场文书
大学迎新生欢迎词
2015/09/29 职场文书
Python还能这么玩之用Python修改了班花的开机密码
2021/06/04 Python