初探Python爬虫Scrapy框架


安装框架

pip install scrapy -i https://pypi.douban.com/simple

创建项目

#打开CMD,cd到自己要保存项目的文件夹
scrapy startproject myspider

目标数据

本次尝试抓取目标链接中的讲师姓名、职称和个人信息。 则修改myspider目录下的items.py文件:

import scrapy
class DeatilItem(scrapy.Item):
    name = scrapy.Field()
    title = scrapy.Field()
    info = scrapy.Field()

创建爬虫

在myspider目录下输入: scrapy genspider itcast "itcast.cn" 然后myspider/spiders目录下会自动生成itcast.py文件 修改itcast.py中的start_urls: start_urls = ["http://www.itcast.cn/channel/teacher.shtml"] 修改parse方法:

def parse(self, response):
        filename = 'teacher.html'
        open(filename,'wb').write(response.body)
        html = etree.HTML(response.body)

在命令行下执行: scrapy crawl itcast 然后即可发现myspider根目录下出现了抓取到页面文件

保存为json

修改itcast.py

import scrapy
from hellospider.items import DetailItem
#调用lxml解析网页,不然会出现TypeError
from lxml import etree

class ItcastSpider(scrapy.Spider):
    name = 'itcast'
    allowed_domains = ['itcast.cn']
    start_urls = ['http://www.itcast.cn/channel/teacher.shtml']

    def parse(self, response):
        filename = 'teacher.html'
        open(filename,'wb').write(response.body)
        html = etree.HTML(response.body)
        for each in html.xpath("//div[@class='li_txt']"):
            item = DetailItem()
            name = each.xpath("h3/text()")
            title = each.xpath("h4/text()")
            info = each.xpath("p/text()")

            item['name'] = name[0]
            item['title'] = title[0]
            item['info'] = info[0]

            yield item

添加管道

修改myspider/pipelines.py

from itemadapter import ItemAdapter
#保存为json,并存入数据库
import json,pymongo

class HellospiderPipeline:
    def process_item(self, item, spider):
        return item

class hellospider(object):
    def __init__(self):
        #创建一个json文件
        self.file = open('teacher.json','wb')
        #连接MongoDB,请修改user和pwd为自己的用户名和密码
        self.client = pymongo.MongoClient('mongodb://user:pwd@localhost:27017')
        #选择数据库,不存在则自动创建
        self.db = self.client.teacher
        #选择表单,不存在则自动创建
        self.collection = self.db.data

    def open_spider(self,spider):
        print('爬虫开始执行',spider.name)

    def process_item(self,item,spider):
        #向json文件中写入
        content = json.dumps(dict(item),ensure_ascii = False) + '\n'
        self.file.write(content.encode('utf-8'))
        #向数据库中写入
        self.collection.insert_one(dict(item))

    def close_spider(self,spider):
        self.file.close()
        print('爬虫执行完毕',spider.name)

然后修改settings.py文件中的ITEM_PIPELINES

#可以同时使用多个管道,后面的数字代表优先级
ITEM_PIPELINES = {
    'hellospider.pipelines.hellospider': 300,
}

开始爬取

再次执行scrapy crawl itcast即可

待解决的问题

1、将json文件和MongoDB分成两个管道时,会出现后执行的管道得到的item为None(与yield的使用有关) 2、对于etree和xpath命令不熟悉,或许可以考虑使用bs4,不过最好还是学习一下