- 爬取这个网上的书籍 http://www.allitebooks.com/security/
- 然后价格等信息在亚马逊上爬取:https://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=xxx # xxx 表示的是下面爬取的 isbn
- 用的是 python3.6
- 微博、小程序查看代码混乱,请查看原文~
准备
- 安装的包
Shell
- $ pip install scrapy
- $ pip install pymysql
- 需要了解的一些 scrapy 知识
Spider
Spider 类想要表达的是:如何抓取一个确定了的网站的数据。比如在 start_urls 里定义的去哪个链接抓取,parse() 方法中定义的要抓取什么样的数据。
当一个 Spider 开始执行的时候,它首先从 start_urls() 中的第一个链接开始发起请求,然后在 callback 里处理返回的数据。
Items
Item 类提供格式化的数据,可以理解为数据 Model 类。
Selectors
Scrapy 的 Selector 类基于 lxml 库,提供 HTML 或 XML 转换功能。以 response 对象作为参数生成的 Selector 实例即可通过实例对象的 xpath() 方法获取节点的数据。
编写
新建项目
Shell
- $ scrapy startproject book_scrapy
这个是创建一个名为 book_scrapy 的项目
新建爬虫
Shell
- $ cd book_sacrpy/
- $ scrapy genspider book_spiser allitebooks.com
- 结构如下:
Source Code
- ├── book_sacrpy
- │ ├── __init__.py
- │ ├── items.py
- │ ├── middlewares.py
- │ ├── pipelines.py
- │ ├── settings.py
- │ └── spiders
- │ ├── __init__.py
- │ └── book_spiser.py
- └── scrapy.cfg
提示:pycharm 里面可以一步到位
编写 Items 类,就是要获取的东西都这里
Python
- # -*- 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 BookItem(scrapy.Item):
- # define the fields for your item here like:
- # name = scrapy.Field()
- # pass
- title = scrapy.Field()
- isbn = scrapy.Field()
- price = scrapy.Field()
说明:
- title 表示书的标题
- isbn 表示书的编号,这样可以从亚马逊里面查到
- price 表示价格,进入亚马逊之后爬取
编写 Spider 爬虫
就是 spider 文件夹下的 book_spider.py 文件,具体代码如下,css,xpath 的分析省略
Python
- # -*- coding: utf-8 -*-
- import scrapy
- from book_sacrpy.items import BookItem
- class BookSpiserSpider(scrapy.Spider):
- name = 'book_spiser'
- allowed_domains = ['allitebooks.com','amazon.com']
- start_urls = ['http://allitebooks.com/security/',]
- def parse(self, response):
- num_pages = int(response.xpath('//a[contains(@title, "Last Page →")]/text()').extract_first())
- base_url = "http://www.allitebooks.com/security/page/{0}/"
- for page in range(1,num_pages):
- yield scrapy.Request(base_url.format(page),dont_filter=True,callback=self.pare_page)
- def pare_page(self,response):
- for ever in response.css('.format-standard'):
- book_url = ever.css('.entry-thumbnail a::attr(href)').extract_first("")
- yield scrapy.Request(book_url,callback=self.pare_book_info)
- def pare_book_info(self,response):
- title = response.css('.single-title').xpath('text()').extract_first()
- isbn = response.xpath('//dd[2]/text()').extract_first('').replace(' ','')
- items = BookItem()
- items['title'] = title
- items['isbn'] = isbn
- amazon_price_url = 'https://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=' + isbn
- yield scrapy.Request(amazon_price_url,callback=self.pare_book_price,meta={'items': items})
- def pare_book_price(self,response):
- items = response.meta['items']
- items['price'] = response.xpath('//span/text()').re(r'\$[0-9]+\.[0-9]{2}?')[0]
- yield items
说明:
- 导入前面编写的 Items,是将爬取的数据通过 yield 方式提交
- 新建类继承的是 scrapy.Spider 类
- name 为爬虫的名字,allowed_domains 表示允许的域名,start_urls 表示爬取的时候的入口 url
运行:
爬取写入到一个 csv 文件
Shell
- $ scrapy crawl book_sacrpy -o books.csv
拓展
写入 mysql
介绍
- pipelines.py 文件,是管道文件,数据传入 item 之后,会再传给 pipeline,所以可以在 pipelines.py 里面写各种存数据的方式
- middlewares.py 文件,是中间件文件,一般写爬虫的 IP 代理,user-agent 等
- settings.py 文件,是设置文件,里面主要是设置开启关闭 pipelines、middlewares、是否爬取 robots.txt 等,也可以在这里面设置一些 mysql 的动态修改的文件等
我们暂时不用中间件,数据库自己提前设置好表头等信息
pipelines.py 代码:
Python
- # -*- coding: utf-8 -*-
- # Define your item pipelines here
- #
- # Don't forget to add your pipeline to the ITEM_PIPELINES setting
- # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
- import pymysql
- from book_sacrpy.items import BookItem
- class BookIntodbPipeline(object):
- def __init__(self):
- self.conn = pymysql.connect("localhost","root","root","book",charset="utf8")
- self.cursor = self.conn.cursor()
- def process_item(self, item, spider):
- insert_sql = '''
- insert into book(title,isbn,price) VALUES ('{}','{}','{}')
- '''
- self.cursor.execute(insert_sql.format(item['title'],item['isbn'],item['price']))
- self.conn.commit()
- # return item
设置 settings.py 文件
Python
- ITEM_PIPELINES = {
- 'book_sacrpy.pipelines.BookIntodbPipeline': 300,
- }
将上面这一段注释掉,写入我们编写的那个 pipeline,数字越大表示越靠后,里面可以写多个 pipeline
运行
Shell
- $ scrapy crawl book_spiser
- 每次运行都要输入三个命令,下面介绍一种快速运行的方式
写一个 run.py 文件,代码如下:
Python
- # coding:utf8
- from scrapy.cmdline import execute
- import sys
- import os
- sys.path.append(os.path.dirname(os.path.abspath(__file__)))
- execute(["scrapy", "crawl", "book_spiser"])
以后只需要运行一个 python run.py
- 微博、小程序查看代码混乱,请查看原文~
- github 开源:https://github.com/liwg1995/spider_learn_again/tree/master/book_sacrpy
本文作者为 olei,转载请注明。
谢谢博主分享!
@残影哈哈,共同学习~
来看看,活跃友链
@陈鑫威博客经常活跃~~~~