python爬虫框架Scrapy安装与爬取示例

环境:python3.6,自带pip

# 安装
pip install scrapy

自动下载所需组件

Installing collected packages: lxml, cssselect, six, w3lib, parsel, pyasn1, attrs, idna, asn1crypto, pycparser, cffi, cryptography, pyOpenSSL, pyasn1-modules,
service-identity, zope.interface, constantly, incremental, Automat, hyperlink, Twisted, queuelib, PyDispatcher, Scrapy

安装出现报错提示

running build_ext
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

下面开始我解决问题的历程

我到http://landinghub.visualstudio.com/visual-cpp-build-tools下载并安装了Microsoft Visual C++ Build Tools(未完全安装),pip install scrapy,再次报错:

error: command 'cl.exe' failed: No such file or directory

于是我分析了一下当前的状态:scrapy没有安装成功,但scrapy所需的组件都下载成功,包括twisted;只是成功安装了部分组件;在安装twisted这个组件的过程中出了错,所以twisted没有安装成功,安装scrapy就卡在了这一步;twisted是一个C++编写的库,需要visual C++的环境去编译;

1、第二个问题如何解决,我猜测应该是Microsoft Visual C++ Build Tools组件安装少了(我在安装它的时候在没有完全安装成功的状态下就取消,因为我C盘快爆了,只安装了52个组件);重新卸载安装?然后我没有那么做,空间占用太大,而且52个组件我能用到有几个,我又不做C/C++开发;
2、看看第一个问题有没有其他解决途径
网上给出了第一个问题的第二种解决途径,访问https://www.lfd.uci.edu/~gohlke/pythonlibs/,下载与安装python和系统位数对应的whl文件,这个文件很小;我的环境是python3.6和win64,所以下载Twisted‑17.9.0‑cp36‑cp36m‑win_amd64.whl,在文件所在位置打开命令行窗口,执行:pip install Twisted-17.9.0-cp36-cp36m-win_amd64.whl

Installing collected packages: Twisted
Successfully installed Twisted-17.9.0

# 该提示信息表示Twisted安装成功,再次安装scrapy
pip install scrapy

# 最后两行日志,scrapy安装成功
Installing collected packages:quequelib,scrapy
Successfully installed queuelib-1.4.2 scrapy-1.4.0

# 查看版本
scrapy
Scrapy 1.4.0 - no active project
···

# 卸载Microsoft Visual C++ Build
# 查看安装组件
pip list

若在爬取的过程中出现如下错误,最好不要网上给的方法去下载可执行文件exe,下面一行代码搞定

File "c:\users\administrator\appdata\local\programs\python\python36\lib\site-packages\twisted\internet\_win32stdio.py", line 9, in 
import win32api
ModuleNotFoundError: No module named 'win32api'

# 安装pypiwin32
pip install pypiwin32

scrapydemo

目标网址:http://www.seu.edu.cn/138/list.htm
1、新建项目

scrapy startproject scrapydemo

2、创建scrapydemo\scrapydemo\spiders\ActivityItem.py

import scrapy


class ActivityItem(scrapy.Item):
    title = scrapy.Field()
    time = scrapy.Field()
    url = scrapy.Field()

3、创建scrapydemo\scrapydemo\spiders\demo.py,使用xpath过滤数据
这里需要三个变量:name 、allowed_domains 、start_urls 、和重写Spider的parser函数,其中allowed_domains可省略;

from scrapy.spider import Spider
from scrapy.selector import Selector

from scrapydemo.spiders.ActivityItem import ActivityItem


class Demo2Spider(Spider):
    name = "demo"
    # allowed_domains = ["www.seu.edu.cn"]
    start_urls = [
        'http://www.seu.edu.cn/138/list.htm',
    ]

    def parse(self, response):

        content = response.body.decode("utf-8", "ignore")
        # Spider.log(self, "Open home page \n\n" + content)
        sel = Selector(response)
        sites = sel.xpath('//*[@id="wp_news_w6"]/ul/li')

        # fo = open("index.html", "w")
        # fo.write(content)
        # Spider.log(self, "\n文件写入完成... ")

        print(len(sites))
        items = []
        for site in sites:
            item = ActivityItem()
            print("\n")
            print(site.xpath('span/a/text()').extract())
            item['title'] = site.xpath('span/a/text()').extract()

            print(site.xpath('span/a/@href').extract())
            item['url'] = site.xpath('span/a/@href').extract()

            print(site.xpath('span/text()').extract())
            item['time'] = site.xpath('span/text()').extract()

            items.append(item)

        # 此处可省略,但后面写入文件或数据库等操作会用到
        return items

4、启动爬虫

scrapy crawl demo

5、将爬取结果写入文件,会在工程根目录下生产demo.json文件

scrapy crawl demo -o demo.json

若json文件文本中文出现unicode编码

# json文件中文为unicode编码解决办法
scrapy crawl demo -o demo.json -s FEED_EXPORT_ENCODING=utf-8

6、debug 调试

先在demo.py中打上断点、然后在settings的同级目录下新建run.py

# -*- coding: utf-8 -*-  
from scrapy import cmdline  

name = 'demo'  
cmd = 'scrapy crawl {0}'.format(name)  
cmdline.execute(cmd.split())

右键->Debug Run,程序就会在断点处停止;

7、爬取目标链接的所有信息
目标链接是一个分页链接,如果想爬取下一页,下下一页或者所有信息是不是都要重写一个爬虫呢?scrapy框架为我们提供了简便的方法,只需要在demo.py中添加如下代码:

next = response.xpath('//*[@id="wp_paging_w6"]/ul/li[2]/a[3]/@href').extract()
url = response.urljoin(next[0])
print(url)
yield scrapy.Request(url=url, callback=self.parse)

爬取下一个的url,并执行回调函数parse,使用递归的方式,将爬取的信息不断地添加到items列表中,注意代码不要加到for循环中哦

你可能感兴趣的:(开发文档撰写)