- 爬取这个网上的书籍 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
- 微博、小程序查看代码混乱,请查看原文~
准备
- 安装的包
$ 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() 方法获取节点的数据。
编写
新建项目
$ scrapy startproject book_scrapy
这个是创建一个名为 book_scrapy 的项目
新建爬虫
$ cd book_sacrpy/ $ scrapy genspider book_spiser allitebooks.com
- 结构如下:
├── book_sacrpy │ ├── __init__.py │ ├── items.py │ ├── middlewares.py │ ├── pipelines.py │ ├── settings.py │ └── spiders │ ├── __init__.py │ └── book_spiser.py └── scrapy.cfg
提示:pycharm 里面可以一步到位
编写 Items 类,就是要获取的东西都这里
# -*- 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 的分析省略
# -*- 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 文件
$ 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 代码:
# -*- 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 文件
ITEM_PIPELINES = {
'book_sacrpy.pipelines.BookIntodbPipeline': 300,
}
将上面这一段注释掉,写入我们编写的那个 pipeline,数字越大表示越靠后,里面可以写多个 pipeline
运行
$ scrapy crawl book_spiser
- 每次运行都要输入三个命令,下面介绍一种快速运行的方式
写一个 run.py 文件,代码如下:
# 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,转载请注明。
谢谢博主分享!
@残影哈哈,共同学习~
来看看,活跃友链
@陈鑫威博客经常活跃~~~~