Scrapy 数据采集

B1:新闻数据采集
一、项目分析

采集对象:四川大学公共管理学院新闻动态栏
采集环境:Ubuntu+MobaXterm
采集目的:采集出四川大学公共管理学院新闻动态栏的191条新闻

二、采集步骤

1.采集新闻数据,首先要分析采集数据的网页有什么内容,对网页进行拆分,了解原网页的结构布局,包含什么字段(元素)。

3.png

由上图可知,该网页是一个标题集+详细页面(list+items)的形式。

5.png

借助网页开发者工具,查看网页源码,可以看见网页对应的各个元素字段。

2.分析采集任务,明确我们要采集的内容,确定要采集的字段(元素)。
基于上一步骤的分析,我们可以看见网页的具体形式,由此确定新闻数据采集的字段:标题(title)、时间(time)、详情(text)、图片(picture)。

3.制定采集方案:爬取步骤,爬取规则
爬取步骤:首先爬出标题集页面的链接,一共有10页。再通过爬出的链接进入详情页爬取每一条新闻的标题、时间、详情以及图片。
爬取规则:利用Xpath规则定位。

友情链接:Xpath语法:http://www.w3school.com.cn/xpath/xpath_syntax.asp

4.编写代码并调试
(1)修改item.py: 定义自己要抓取的数据。
# -- coding: utf-8 --

  # Define here the models for your scraped items
  #
  # See documentation in:
  # http://doc.scrapy.org/en/latest/topics/items.html

  import scrapy


  class NItem(scrapy.Item):
  # define the fields for your item here like:
  # name = scrapy.Field()
  time = scrapy.Field()
  title = scrapy.Field()
  text = scrapy.Field()
  picture = scrapy.Field()
  pass

tips:注意class的名称NItem,在写spiders中会用到。

(2)编写spiders:
newsspider.py:

import scrapy
from news.items import NItem

class NewsSpider(scrapy.Spider):
name="newsspider"#设置爬虫name,这是唯一定位实例的属性
start_urls=[     #爬取的起始网页
'http://ggglxy.scu.edu.cn/index.php?c=special&sid=1',
]
def parse(self,response):
    for href in response.xpath('//div[@class="news_c fr"]/h3[@class="mb10"]/a/@href').extract():
        yield scrapy.Request(response.urljoin(href),callback=self.parse_news)#将爬出的链接传值给parse函数
    next_page=response.xpath('//div[@class="pager cf tr pt10 pb10 mt30 mobile_dn"]/li[last()-1]/a/href').extract()
    last_page=response.xpath('//div[@class="pager cf tr pt10 pb10 mt30 mobile_dn"]/li[last()]/a/href').extract()
    if last_page is not None:#判断最后一页是否为空,如果不是,继续爬取,如果是,则停止爬取
        next_page="http://ggglxy.scu.edu.cn/"+next_page
        yield scrapy.Request(next_page, callback=self.parse)
def parse_news(self,response):
        item = NewsItem()
        item['time'] = response.xpath('//div[@class="detail_zy_title"]/p/text()').extract()#使用xpath方式选择信息
        item['title'] = response.xpath('//div[@class="detail_zy_title"]/h1/text()').extract()
        item['text'] = response.xpath('//div[@class="detail_zy_c pb30 mb30"]/p/span/text()').extract()
        item['picture'] = response.xpath('//div[@class="detail_zy_c pb30 mb30"]/p/image/@src').extract()
        yield item

tips:
(1)注意news.items中news一定是项目名称。

 import scrapy
from news.items import NItem#必须要写,否则NItem没有定义
class NewsSpider(scrapy.Spider):  

没有写from news.items import NItem:

6.png

没有将news.items写成项目名称:

7.png

(2)注意括号,符号,单词拼写等细节。

 item['time'] = response.xpath('//div[@class="detail_zy_title"]/p/text()').extract()
  item['title'] = response.xpath('//div[@class="detail_zy_title"]/h1/text()').extract()
  item['text'] = response.xpath('//div[@class="detail_zy_c pb30 mb30"]/p/span/text()').extract()
  item['picture'] = response.xpath('//div[@class="detail_zy_c pb30 mb30"]/p/image/@src').extract()  

若将中括号[]写成():

2.png

(3)路径错误。
我之前爬错了网页,结果什么都没有爬出来:

8.png

(4)注意设置判断,结束爬取。

  if last_page is not None:
    next_page="http://ggglxy.scu.edu.cn/"+next_page
    yield scrapy.http.Request(next_page,callback=self.parse)  

如果不设置判断,就只爬出来一部分数据:

9.png

5.提取数据

10.png

得到n.json:

12.png

若要得到中文的数据,可以修改settings.py: 添加

   FEED_EXPORT_ENCODING = 'utf-8'

如下图:

  SPIDER_MODULES = ['teacher.spiders']
  NEWSPIDER_MODULE = 'teacher.spiders'
  FEED_EXPORT_ENCODING = 'utf-8'#中文    

也可以在执行爬虫的时候,直接输入以下命令:

scrapy crawl yourspider -o name.json -s FEED_EXPORT_ENCODING=utf-8

得到news.json:

11.png

友情链接:unicode转中文:http://www.phpstudy.net/c.php/91841.html

B2:教师资料采集

步骤和方法与B1相同。
得到相应文件:
1.item.py:

import scrapy


class TeachersItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
name = scrapy.Field()
position = scrapy.Field()
description = scrapy.Field()  

2.tc.py

import scrapy
from teacher.items import TeachersItem

class TeacherSpider(scrapy.Spider):
name="tc"
start_urls=[
'http://ggglxy.scu.edu.cn/index.php?c=article&a=type&tid=18&page_1_page=1',
]

def parse(self,response):
    for href in response.xpath('//div[@class="l fl"]/a/@href').extract():
        yield scrapy.http.Request(response.urljoin(href), callback=self.parse_teacher)
  
    next_page=response.xpath('//div[@class="pager cf tc pt10 pb10 mobile_dn"]/li[last()-1]/a/@href').extract_first()
    last_page=response.xpath('//div[@class="pager cf tc pt10 pb10 mobile_dn"]/li[last()]/a/@href').extract_first()
    if last_page is not None:
        next_page="http://ggglxy.scu.edu.cn/"+next_page
        yield scrapy.http.Request(next_page, callback=self.parse)
  
def parse_teacher(self,response):
    item = TeachersItem()
    item['name'] = response.xpath('//div[@class="r fr"]/h3/text()').extract()
    item['position'] = response.xpath('//div[@class="r fr"]/p/text()').extract()
    item['description'] = response.xpath('//div[@class="r fr"]/div/text()').extract()
    yield item  

3.t.json

22.png
总结

耐心+细心

你可能感兴趣的:(Scrapy 数据采集)