Scrapy的使用方法

Scrapy框架

什么是scrapy

Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能够快速的抓取。

文件目录

scrapy.cfg    #项目的配置文件
items.py      #提取要爬取的字段,字典保存爬取到的数据的容器
middlewares   #自定义中间件的地方
pipelines.py  #管道,保存数据
settings.py   #项目的设置文件 设置文件,UA,启动管道
spiders       #存储爬虫代码目录
    itcast.py   #写爬虫的文件

爬虫步骤:

1.创建一个scrapy项目
scrapy startproject mySpider   #mySpider是项目名字
2.生成一个爬虫
scrapy genspider itcast itcast.cn  #itcast是爬虫名字,"itcast.cn"限制爬虫地址,防止爬到其他网站
3.提取数据
完善spiders,使用xpath等方法
4.启动爬虫
scrapy crawl 爬虫名字    #crawl(抓取的意思)
Scrapy的使用方法_第1张图片
image.png

spider内容

spider翻页

# -*- coding: utf-8 -*-
import scrapy
#导入items
from tencent.items import TencentItem

#自定义spider类,继承自scrapy.Spider
class ItcastSpider(scrapy.Spider):
    name = 'itcast' #爬虫名字<爬虫启动时候使用:scrapy crawl itcast>
    #允许爬取的范围,防止爬虫爬到了别的网站
    allowed_domains = ['tencent.com']
    #开始爬取的地址,下载中间件提取网页数据
    start_urls = ['https://hr.tencent.com/position.php']
    #数据提取方法,接收下载中间件传过来的response(响应)
    def parse(self, response):
        #处理start_url地址对应的响应
        #提取数据
        # reti = response.xpath("//div[@class='tea_con']//h3/text()").extract()
        # print(reti)

        #分组,[1:-1]切片,不要第一条数据
        li_list = response.xpath("//table[@class="tablelist"]/tr")[1:-1]
        for li in li_list:
            #在item中定义要爬取的字段,以字典形式传入
            item = TencentItem()
            item["name"] = li.xpath(".//h3/text()").extract_first()
            item["title"] = li.xpath(".//h4/text()").extract_first()
            #yield可以返回request对象,BaseItem(items.py中的类),dict,None
            yield item  #yield传到pipeline
        #找到下一页url地址
        next_url = response.xpath('//a[@id="next"]/@href').extract_first()
        #如果url地址的href="地址"不等于javascript:;
        if next_url != "javascript:;":
            next_url = "https://hr.tencent.com/"+ next_url
            #把next_url的地址通过回调函数callback交给parse方法处理
            yield scrapy.Request(next_url,callback=self.parse)

爬取详细页和翻页

# -*- coding: utf-8 -*-
import scrapy
from yangguang.items import YangguangItem

class YgSpider(scrapy.Spider):
    name = 'yg'
    allowed_domains = ['sun0769.com']
    start_urls = ['http://wz.sun0769.com/index.php/question/questionType?type=4&page=0']

    def parse(self, response):
        tr_list = response.xpath("//div[@class='greyframe']/table[2]/tr/td/table/tr")
        for tr in tr_list:
            item = YangguangItem()
            item["title"] = tr.xpath("./td[2]/a[@class='news14']/@title").extract_first()
            item["href"] = tr.xpath("./td[2]/a[@class='news14']/@href").extract_first()
            item["publish_date"] = tr.xpath("./td[last()]/text()").extract_first()
            #执行进入url地址,再把item传到下面parse_detail,提取详细页的内容
            yield scrapy.Request(item["href"],callback=self.parse_detail,meta={"item":item})
        #翻页
        #获取url地址
        next_url = response.xpath("//a[text()='>']/@href").extract_first()
        #如果下一页url地址不为空,进入下一页连接
        if next_url is not None:
            yield scrapy.Request(next_url,callback=self.parse)

    #处理详情页
    def parse_detail(self,response):
        #item接收meta传过来的item,在item字典里继续为item添加内容
        item = response.meta["item"]
        #拿到详细页的内容
        item["content"] = response.xpath("//div[@class='c1 text14_2']//text()").extract()
        #拿到详细页的图片地址
        item["content_img"] = response.xpath("//div[@class='c1 text14_2']//img/@src").extract()
        #给图片前面加上http://wz.sun0769.com
        item["content_img"] = ["http://wz.sun0769.com" + i for i in item["content_img"]]
        #把item传给pipeline
        yield item

items(存储爬取字段)

import scrapy
#scrapy.Item是一个字典
class TencentItem(scrapy.Item):
#scrapy.Field()是一个字典
url = scrapy.Field()
name = scrapy.Field()

使用pipeline(管道)

from demo1 import settings
import pymongo

class Demo1Pipeline(object):
    def __init__(self):
        #连接mongodb数据库(数据库地址,端口号,数据库)
        client = pymongo.MongoClient(host=settings.MONGODB_HOST, port=settings.MONGODB_PORT)
        #选择数据库和集合
        self.db = client[settings.MONGODB_DBNAME][settings.MONGODB_DOCNAME]
    def process_item(self, item, spider):
        data = dict(item)
        self.db.insert(data)

#完成pipeline代码后,需要在setting中设置开启
ITEM_PIPELINES = {
  #开启管道,可以设置多个管道,'管道地址数值':越小越先执行
  'mySpider.pipelines.MyspiderPipeline': 300,
}
# MONGODB 主机环回地址127.0.0.1
MONGODB_HOST = '127.0.0.1'
# 端口号,默认是27017
MONGODB_PORT = 27017
# 设置数据库名称
MONGODB_DBNAME = 'DouBan'
# 存放本次数据的表名称
MONGODB_DOCNAME = 'DouBanMovies'
注意
  • pipeline中process_item方法名不能修改,修改会报错
  • pipeline(管道)可以有多个
  • 设置了pipelines必须开启管道,权重越小优先级越高

把数据保存到mongodb中

#导入mongodb的包
from pymongo import MongoClient
#实例化client,建立连接
client = MongoClient(host='127.0.0.1',port = 27017)
#选择数据库和集合
collection = client["tencent"]["hr"]

class TencentPipeline(object):
    def process_item(self, item, spider):
        #传过来的数据是对象,把item转化为字典
        item = dict(item)
        #把数据存入mongodb数据库
        collection.insert(item)
        print(item)
        return item

你可能感兴趣的:(Scrapy的使用方法)