Python爬虫实战4,运营学python之爬虫高端篇

1. Scrapy框架

  Scrapy是python下实现爬虫功能的框架,能够将数据解析、数据处理、数据存储合为一体功能的爬虫框架。

Scrapy是一个应用程序框架,用于抓取web站点和提取结构化数据,这些数据可以用于广泛的应用,如数据挖掘、信息处理。尽管Scrapy最初是为web抓取而设计的,但它也可以使用api(比如Amazon Associates的web服务)或作为一个通用的web爬虫程序来提取数据。

这是我自己在学习python 3爬虫时的小笔记,做备忘用,难免会有一些错误和疏漏,望指正~~~
Python 3 爬虫学习笔记 (一)
Python 3 爬虫学习笔记 (二)
Python 3 爬虫学习笔记 (三)
Python 3 爬虫学习笔记 (四)
Python 3 爬虫学习笔记 (六)

2. Scrapy安装

1 环境安装

最初Scrapy是不支持python3的,现在已经支持了,所以我们主要还是使用python3来实现。


1. 安装依赖包

yum install gcc libffi-devel python-devel openssl-devel -y
yum install libxslt-devel -y

1.1Ubuntu 14.04 或以上版本安装

主要注意相关依赖包其它linux版本基本相似(会玩linux,这个都是小菜一碟,不多讲解)

sudo apt-get install python-dev python-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev

sudo apt-get install python3 python3-dev

pip install scrapy

六、Scrapy初体验

之前大概学习了下通过urllib和Beautiful Soup 进行简单数据爬取的流程,但是那只适用于一些简单的、数据量比较小的爬虫项目,如果需要爬取的数据量比较大的话,之前的方法必定非常缓慢,所以就有了Scrapy,Scrapy是一个快速的web抓取框架,可抓取web站点并从页面中提取结构化的数据。Scrapy给我们提供了许多的爬虫基类,我们可以直接继承使用,当然,既然Scrapy是一个框架,我们也可以根据自己的需要对它进行修改,下面我们就慢慢来看Scrapy的使用。

Scrapy is an application framework for crawling web sites and extracting structured data which can be used for a wide range of useful applications, like data mining, information processing or historical archival.
Even though Scrapy was originally designed for web scraping, it can also be used to extract data using APIs (such as Amazon Associates Web Services ) or as a general purpose web crawler.

 2. 安装scrapy

pip install scrapy
pip install twisted==13.1.0

 注意事项:scrapy和twisted存在兼容性问题,如果安装twisted版本过高,运行scrapy startproject project_name的时候会提示报错,安装twisted==13.1.0即可。

1.2 windows上安装

windows上安装稍微复杂一点,首先要安装Anaconda,Anaconda下载地址:
百度网盘下载 密码:3kjd 官网下载地址
Anaconda安装很简单,就是下一步,下一步即可,安装完后一定要记得配置环境变量,不然也会出错,配置步骤如下:
图片 1
按照箭头方向配置即可,注意Anaconda安装的路径要与你的安装路径对应。配置完成后直接cmd,后运行命令:

conda install  scrapy

如下图:
图片 2
选择Y回车
图片 3
Scrapy就安装完成了。

(一)安装(Windows)

Scrapy是纯Python编写的,所以需要一些比较重要的的Python依赖包:

  • lxml, an efficient XML and HTML parser
  • parsel, an HTML/XML data extraction library written on top of lxml,
  • w3lib, a multi-purpose helper for dealing with URLs and web page encodings
  • twisted, an asynchronous networking framework
  • cryptography and pyOpenSSL, to deal with various network-level security needs

看着依赖包比较多,其实安装起来并不复杂,以管理员的身份运行Windows命令提示符,在以安装Python的前提下,运行:

pip install scrapy

pip会自动下载相关依赖包,如果顺利的话,会直接安装完成。

要注意的是,确认一下python的版本,pip会根据系统自动安装相关包,即如果系统是64位的,pip就会安装64位的包,但是twisted的版本一定要和python的一样,如果操作系统是64位的,python是32位的,pip直接安装的twisted安装就会出错。

如果pip安装twisted时出错,在命令行输入python,查看本地python版本,然后到这里下载和python版本相同的whl文件,使用pip install xxx.whl安装,完成后再执行一遍pip install scrapy即可。

在命令行输入scrapy, 若不报错,则安装完成。

3. 基于Scrapy爬取数据并存入到CSV

3.1. 爬虫目标,获取简书中热门专题的数据信息,站点为

图片 4

2 Scrapy使用

(二) 第一个Scrapy项目

照例,先上官方文档 1.3,找了一下网上翻译的文档都是0.24或者0.24版,所以建议大家还是看官方最新的英文版比较好。

打开命令提示符,进入想要创建项目的目录,运行

scrapy startproject scrapyTest

Paste_Image.png

项目创建完成,让我们来看一下项目结构,执行:

tree /f

Paste_Image.png

└─scrapyTest
    │  scrapy.cfg           # 配置文件(deploy configuration file)
    │
    └─scrapyTest
        │  items.py         # 项目中的item文件(project items definition file)
        │  middlewares.py   # 中间件
        │  pipelines.py     # 项目中的管道文件(project pipelines file)
        │  settings.py      # 项目中的设置文件(project settings file)
        │  __init__.py
        │
        ├─spiders           # 存放爬虫的文件夹(a directory where you'll later put your spiders)
        │  │  __init__.py
        │  │
        │  └─__pycache__
        └─__pycache__

进入spiders目录,新建test_spider.py如下:

# -*- coding:utf-8 -*-

import scrapy
from bs4 import BeautifulSoup


class tsSpride(scrapy.Spider):
    name = 'test' # 爬虫的唯一名字,在项目中爬虫名字一定不能重复

    # start_requests() 必须返回一个迭代的Request
    def start_requests(self):
        # 待爬取的URL列表
        urls = ['http://www.jianshu.com/',]
        # 模拟浏览器
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
        for url in urls:
            yield scrapy.Request(url=url, headers=headers, callback=self.parse)

    # 处理每个请求的下载响应
    def parse(self, response):
        soup = BeautifulSoup(response.body, 'html.parser')
        titles = soup.find_all('a', 'title')
        for title in titles:
            print(title.string)

在命令行输入

scrapy crawl test

结果如下:

Paste_Image.png

上述代码Scrapy为start_requests 中的每个URL创建了scrapy.Request对象,并将 parse() 方法作为回调函数(callback)赋值给了Request(Scray中parse()为默认回调方法)。

The parse() method will be called to handle each of the requests for those URLs, even though we haven’t explicitly told Scrapy to do so. This happens because parse() is Scrapy’s default callback method, which is called for requests without an explicitly assigned callback.

上面代码中用了Beautiful Soup来处理爬下来的数据,而Scrapy也有Selector来处理数据,今天先到这里,下次再用一个具体的小项目来更详细地介绍Scrapy。

3.2. 爬取内容

  需要爬取专题的内容包括:专题内容、专题描述、收录文章数、关注人数,Scrapy使用xpath来清洗所需的数据,编写爬虫过程中可以手动通过lxml中的xpath获取数据,确认无误后再将其写入到scrapy代码中,区别点在于,scrapy需要使用extract()函数才能将数据提取出来。

2.1 创建一个项目

在开始爬取之前,您必须创建一个新的Scrapy项目。 进入你打算存储代码的目录中,运行下列命令:

scrapy startproject tutorial

如图:
图片 5
创建完成后的目录结构如下:
图片 6

3.3 创建爬虫项目

[root@HappyLau jianshu_hot_topic]# scrapy startproject jianshu_hot_topic

#项目目录结构如下:
[root@HappyLau python]# tree jianshu_hot_topic
jianshu_hot_topic
├── jianshu_hot_topic
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── items.py
│   ├── items.pyc
│   ├── middlewares.py
│   ├── pipelines.py
│   ├── pipelines.pyc
│   ├── settings.py
│   ├── settings.pyc
│   └── spiders
│       ├── collection.py
│       ├── collection.pyc
│       ├── __init__.py
│       ├── __init__.pyc
│       ├── jianshu_hot_topic_spider.py    #手动创建文件,用于爬虫数据提取
│       └── jianshu_hot_topic_spider.pyc
└── scrapy.cfg

2 directories, 16 files
[root@HappyLau python]# 

2.2 pycharm中调试scrapy代码

如果在pycharm中调试scrapy,需要安装scrapy,在安装scrapy之前还有几个依赖文件也要安装,如下:

  • zope.interface
  • pyOpenSSL
  • twisted 我下载的版本地址 更多版本地址
  • liblxml2dom
  • lxml

twisted报错
这些包都可以用pycharm插件工具安装,但其中安装twisted时候会出现报错,报错内容大概如下:

building 'twisted.test.raiser' extension
error: Microsoft Visual C   14.0 is required. Get it with "Microsoft Visual C   Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools

twisted报错解决办法如下:

下载twisted对应版本的whl文件(如我的Twisted‑17.5.0‑cp36‑cp36m‑win_amd64.whl)下载地址上文已经给出,cp后面是python版本,amd64代表64位,运行命令,注意Twisted文件的路径:
pip install Twisted-17.5.0-cp36-cp36m-win_amd64.whl

解决上面报错后在pip install scrapy就OK了。

pycharm无法直接调试scrapy
pycharm是无法直接调试scrapy的,需要我们在项目中做一些配置,配置如下图:
图片 7
图一
图一中quotes_spider.py名称是你自己定义的,类中的name = "quotes"名称也是自定义的
图片 8
图二
然后在scrapy.cfg的同级目录下创建一个main.py文件,内容如上图,这里要注意cmdline.execute("scrapy crawl quotes".split())中的quotes要与图一中的name=“quotes”是对应的。每次执行main.py就可以了。
quotes_spider.py代码如下:

import scrapy

class QuotesSpider(scrapy.Spider):
    name = "quotes"

    def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
            'http://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = 'quotes-%s.html' % page
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log('Saved file %s' % filename)

如上代码,我们的爬虫子类scrapy.Spider并定义了一些属性和方法:
name:标识爬虫。它必须在一个项目中是唯一的,不能为不同的爬虫设置相同的名称。
start_requests():必须返回一个可重复的请求(您可以返回一个请求列表,或者编写一个生成器函数),这将使爬虫开始爬行。后续请求将依次从这些初始请求中生成。
parse():将调用一个方法来处理每个请求所下载的响应。响应参数是保存页面内容的TextResponse的一个实例,并且有进一步的帮助方法来处理它。parse()方法通常解析响应,提取解析的数据,并找到新的url来跟踪和创建新的请求。
win32api报错
按照上面配置完成后,你会发现提示no module name win32api错误,这是因为没有安装win32的模块造成的
win32api报错解决办法
安装win32模块,安装有两种方式:
1.pycharm安装工具直接安装
2.下载win32包用pip install 包名 方式安装我下载的包 更多版本包
我这边pycharm直接安装是失败的,所以我用的第二种安装方式

pip install pywin32-222-cp36-cp36m-win_amd64.whl 

安装完之后问题解决,运行main.py后结果如下:
图片 9

 3.4 代码内容

1. items.py代码内容,定义需要爬取数据字段
# -*- coding: utf-8 -*-

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

import scrapy
from scrapy import Item
from scrapy import Field

class JianshuHotTopicItem(scrapy.Item):
 '''
 @scrapy.item,继承父类scrapy.Item的属性和方法,该类用于定义需要爬取数据的子段
 '''
 collection_name = Field()
 collection_description = Field()
 collection_article_count = Field()
 collection_attention_count = Field()

2. piders/jianshu_hot_topic_spider.py代码内容,实现数据获取的代码逻辑,通过xpath实现
[root@HappyLau jianshu_hot_topic]# cat spiders/jianshu_hot_topic_spider.py
#_*_ coding:utf8 _*_

import random
from time import sleep
from scrapy.spiders import CrawlSpider
from scrapy.selector import Selector
from scrapy.http import Request
from jianshu_hot_topic.items import JianshuHotTopicItem 

class jianshu_hot_topic(CrawlSpider):
 '''
 简书专题数据爬取,获取url地址中特定的子段信息
 '''
 name = "jianshu_hot_topic"
 start_urls = ["https://www.jianshu.com/recommendations/collections?page=2&order_by=hot"]

 def parse(self,response):
  '''
  @params:response,提取response中特定字段信息
  '''
  item = JianshuHotTopicItem()
  selector = Selector(response)
  collections = selector.xpath('//div[@class="col-xs-8"]') 
  for collection in collections:
   collection_name = collection.xpath('div/a/h4/text()').extract()[0].strip()
                 collection_description = collection.xpath('div/a/p/text()').extract()[0].strip()
                 collection_article_count = collection.xpath('div/div/a/text()').extract()[0].strip().replace('篇文章','')
                 collection_attention_count = collection.xpath('div/div/text()').extract()[0].strip().replace("人关注",'').replace("· ",'') 
   item['collection_name'] = collection_name
   item['collection_description'] = collection_description
   item['collection_article_count'] = collection_article_count 
   item['collection_attention_count'] = collection_attention_count

   yield item


  urls = ['https://www.jianshu.com/recommendations/collections?page={}&order_by=hot'.format(str(i)) for i in range(3,11)]
  for url in urls:
   sleep(random.randint(2,7))
   yield Request(url,callback=self.parse)

3. pipelines文件内容,定义数据存储的方式,此处定义数据存储的逻辑,可以将数据存储载MySQL数据库,MongoDB数据库,文件,CSV,Excel等存储介质中,如下以存储载CSV为例:
[root@HappyLau jianshu_hot_topic]# cat pipelines.py
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html


import csv 

class JianshuHotTopicPipeline(object):
    def process_item(self, item, spider):
     f = file('/root/zhuanti.csv','a ')
 writer = csv.writer(f)
 writer.writerow((item['collection_name'],item['collection_description'],item['collection_article_count'],item['collection_attention_count']))
        return item

4. 修改settings文件,
ITEM_PIPELINES = { 
    'jianshu_hot_topic.pipelines.JianshuHotTopicPipeline': 300,
}

3 开始scrapy

 3.5 运行scrapy爬虫

  返回到项目scrapy项目创建所在目录,运行scrapy crawl spider_name即可,如下:

[root@HappyLau jianshu_hot_topic]# pwd
/root/python/jianshu_hot_topic
[root@HappyLau jianshu_hot_topic]# scrapy crawl jianshu_hot_topic
2018-02-24 19:12:23 [scrapy.utils.log] INFO: Scrapy 1.5.0 started (bot: jianshu_hot_topic)
2018-02-24 19:12:23 [scrapy.utils.log] INFO: Versions: lxml 3.2.1.0, libxml2 2.9.1, cssselect 1.0.3, parsel 1.4.0, w3lib 1.19.0, Twisted 13.1.0, Python 2.7.5 (default, Aug  4 2017, 00:39:18) - [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)], pyOpenSSL 0.13.1 (OpenSSL 1.0.1e-fips 11 Feb 2013), cryptography 1.7.2, Platform Linux-3.10.0-693.el7.x86_64-x86_64-with-centos-7.4.1708-Core
2018-02-24 19:12:23 [scrapy.crawler] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'jianshu_hot_topic.spiders', 'SPIDER_MODULES': ['jianshu_hot_topic.spiders'], 'ROBOTSTXT_OBEY': True, 'USER_AGENT': 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0', 'BOT_NAME': 'jianshu_hot_topic'}

 查看/root/zhuanti.csv中的数据,即可实现。

 

3.1 scrapy流程及总体架构

执行完main.py后,检查当前目录中的文件,你应该注意到已经创建了两个新文件:quotes-1.html和quotes-2.html,并且带有相应的url的内容。那通过scrapy是如何工作的呢?接下来我们讲一下scrapy的工作流程及总体架构。下图描述了scrapy的架构及它的组件是如何交互的:
图片 10

从上图可以看出scrapy中的数据流由执行引擎控制,流程如下:

  • 1.引擎(Engine)得到最初初始的请求,通过spiders去爬取;
  • 2.引擎(Engine)在调度器(Scheduler)中调度请求,并寻找下一个请求去爬取;
  • 3.调度程序(Scheduler)将下一个请求返回给引擎(Engine);
  • 4.引擎(Engine)将请求发送给下载器(Downloader),通过下载器(Downloader)中间件(请参阅processrequest());
  • 5.一旦页面完成下载后,下载器(Downloader)会生成一个响应(使用该页面)并将其通过Downloader中间件发送到引擎;
  • 6.引擎(Engine)接收来自下载器(Downloader)的响应,并将其发送给spiders进行处理,通过spiders中间件;
  • 7.spiders处理响应并返回提取的items 和新请求返回到引擎,通过爬行器spider中间件;
  • 8.引擎(Engine)将处理过的项目发送到项目管道(Item Pipelines),然后将处理过的请求发送到调度程序(Scheduler),并请求下一个可能要爬取的请求;
  • 9.这个过程重复(从步骤1)直到不再有来自调度程序(Scheduler)的请求。

4. 遇到的问题总结

  1. twisted版本不见容,安装过新的版本导致,安装Twisted (13.1.0)即可

2. 中文数据无法写入,提示'ascii'错误,通过设置python的encoding为utf即可,如下:

>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.setdefaultencoding('utf8')
>>> sys.getdefaultencoding()
'utf8'

 3. 爬虫无法获取站点数据,由于headers导致,载settings.py文件中添加USER_AGENT变量,如:

USER_AGENT="Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"

 Scrapy使用过程中可能会遇到结果执行失败或者结果执行不符合预期,其现实的logs非常详细,通过观察日志内容,并结合代码 网上搜索资料即可解决。

3.2 scrapy各组件功能

Scrapy引擎(Engine)
引擎负责控制系统的所有组件之间的数据流,当某些动作发生时触发事件
调度程序(Scheduler)
调度程序接收来自引擎的请求,并在引擎请求时对它们进行排队,以便在稍后(也对引擎)请求时提供它们
下载器(Downloader)
下载器负责获取web页面,并将它们提供给引擎,而引擎又将它们提供给spiders
Spiders
Spiders是类,它定义了一个特定的站点(或一组站点)如何被抓取,包括如何执行爬取(也就是跟踪链接)以及如何从它们的页面中提取结构化数据(例如抓取项目)。换句话说,Spiders是定义为特定站点爬行和解析页面的定制行为(或者,在某些情况下,是一组站点)的定制行为。
Item Pipeline
Item Pipeline负责处理由spiders提取出来的item,典型的处理有清理、 验证及持久化(例如存取到数据库中)。
下载器中间件(Downloader middlewares)
Downloader中间件是一种特定的钩子,它位于引擎和Downloader之间,当请求从引擎传递到Downloader时,以及从Downloader传递到引擎的响应。
Spider middlewares
Spider middlewares是位于引擎和spiders之间的特定钩子,能够处理spiders输入(响应)和输出(items和requests)。
事件驱动网络
scrapy是用Twisted编写的,它是一种流行的、用于Python的事件驱动的网络框架。因此,它是使用非阻塞(又称为异步)的并发性来实现的。

scrapy入门,这一篇就结束了,欢迎批评指正~!

本文由星彩网app下载发布于计算机编程,转载请注明出处:Python爬虫实战4,运营学python之爬虫高端篇

TAG标签: 星彩网app下载
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。