文章目录

    • 安装
    • 步骤
      • 新建爬虫项目 - scrapy startproject
      • 明确数据目标 - disease/items.py
      • 制作网页爬虫 - spiders/MedicaldataSpider.py
          • 创建爬虫
          • 配置爬虫
          • 取数据
          • 提取其他信息
          • 保存数据


安装

sudo pip install scrapy

python3环境配置


步骤

  • 新建爬虫项目 (scrapy startproject name)
  • 明确数据目标 (编写 items.py)
  • 制作网页爬虫 (spiders/xxspider.py)
  • 存储爬取内容 (pipelines.py)

新建爬虫项目 - scrapy startproject

终端进入项目目录

scrapy startproject spiderName
spiderName - 项目名称

系统创建一个 spiderName 文件夹,目录结构:

spiderName/
    scrapy.cfg                项目配置文件
    spiderName/               Python模块 - 从这里引用代码
        __init__.py
        items.py              目标文件
        pipelines.py
        settings.py           设置文件
        spiders/              存储爬虫代码目录
            __init__.py
            ...

明确数据目标 - disease/items.py

目标:抓取 http://yao.xywy/class/4-0-0-1-0-1.htm 网站里的药品的名称、生产公司和功能主治

打开 disease 目录下的 items.py

  • Item 定义结构化数据字段,用来保存爬取到的数据
    scrapy.Item 创建一个类
    scrapy.Field 定义类型类属性

创建一个 MedicaldataItem 类,构建 item 模型

import scrapy

class MedicaldataItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    name = scrapy.Field()  # 药品名称
    company = scrapy.Field()  # 生产公司
    function = scrapy.Field()  # 功能主治
    


制作网页爬虫 - spiders/MedicaldataSpider.py

爬虫功能 : 爬 => 取


创建爬虫

创建一个名为Medicaldata的爬虫,并指定爬取域的范围:
cd disease

scrapy genspider Medicaldata "http://yao.xywy"

打开 disease/spider目录里的 Medicaldata.py,默认增加了下列代码:

import scrapy

class MedicaldataSpider(scrapy.Spider):
    name = 'Medicaldata'
    allowed_domains = ['yao.xywy']
    start_urls = ['http://yao.xywy']

    def parse(self, response):
        pass

用scrapy.Spider类创建一个子类来建立一个Spider,其下有三个强制的属性 和 一个方法。

  • name = “”
    爬虫的唯一识别名称

  • allow_domains = []
    搜索的域名范围
    规定爬虫只爬取这个域名下的网页,不存在的URL会被忽略。

  • start_urls = ()
    爬取起始URL
    爬虫从这里开始抓取数据,所以,第一次下载的数据将会从这些urls开始。其他子URL将会从这些元祖URL中继承性生成。

  • parse(self, response)
    解析的方法
    URL传回Response对象作为唯一参数,用来

    1. 解析返回的网页数据(response.body)
    2. 提取结构化数据(生成item)
    3. 生成需要下一页的URL请求。


配置爬虫

将start_urls的值修改为需要爬取的第一个url

start_urls = ['http://yao.xywy/class/4-0-0-1-0-1.htm']

修改parse()方法

def parse(self, response):
    filename = "drug.html"
    open(filename, 'wb').write(response.body)

原文为 open(filename, ‘w’).write(response.body)
报错
TypeError: write() argument must be str, not bytes
python3 w为写字符,wb为二进制

参考:https://blog.csdn/kingyuan666/article/details/81214954

在disease目录下执行:
scrapy crawl Medicaldata

[scrapy] INFO: Spider closed (finished) 执行完成
drug.html 中为爬取网页的源代码



取数据

爬取整个网页完毕,接下来进行取数据

获取 xpath 地址
利用 Chrome
右键 => 检查 => copy => copy xpath


xpath:
/html/body/div[6]/div[2]/div[1]/a

XPath 表达式简例

/html/head/title: 选择HTML文档中 <head> 标签内的 <title> 元素
/html/head/title/text(): 选择上面提到的 <title> 元素的文字
//td: 选择所有的 <td> 元素
//div[@class="mine"]: 选择所有具有 class="mine" 属性的 div 元素

举例 - 读取网站 http://yao.xywy/ 的网站标题,

Medicaldata.py 文件代码如下:

import scrapy

class MedicaldataSpider(scrapy.Spider):
    name = 'Medicaldata'
    allowed_domains = ['yao.xywy']
    start_urls = ['http://yao.xywy/class/4-0-0-1-0-1.htm']

    def parse(self, response):
        # 获取网站标题
        context = response.xpath('/html/head/title/text()')
        
        # 提取网站标题
        title = context.extract_first()
        print(title)
        pass

执行以下命令:

scrapy crawl Medicaldata


中西药品_寻医问药药品网



提取其他信息

引入在 disease/items.py 里定义的 MedicaldataItem 类
然后将得到的数据封装到一个 MedicaldataItem 对象中

注意缩进

from disease.items import MedicaldataItem

def parse(self, response):
        
        # 存放疾病信息的集合
        items = []
        
        for each in response.xpath('//div[@class="h-drugs-item"]'):
            # 将我们得到的数据封装到一个 `ItcastItem` 对象
            item = MedicaldataItem()
            #extract()方法返回的都是unicode字符串
            name = each.xpath('div/a/@target').extract()
            company = each.xpath('div/span/text()').extract()
            function = each.xpath('div[2]/div[2]/div[2]/text()').extract()
            
            #xpath返回的是包含一个元素的列表
            item['name'] = name[0]
            item['company'] = company[0]
            item['function'] = function[0]
            
            items.append(item)

        # 直接返回最后数据
        return items



保存数据

-o 输出指定格式的文件,命令如下:

  • json 格式
    scrapy crawl Medicaldata -o drug.json

  • json lines格式,默认为Unicode编码
    scrapy crawl Medicaldata -o drug.json

  • csv 逗号表达式,可用Excel打开
    scrapy crawl Medicaldata -o drug.csv

  • xml格式
    scrapy crawl Medicaldata -o drug.xml

ERROR
scrapy 爬虫返回 json格式内容为 unicode 编码

解决方案
在settings.py文件中增加一行,导出时强制为’utf-8’即可转换为中文
FEED_EXPORT_ENCODING = 'utf-8'
http://wwwblogs/mrtop/p/10185507.html

爬取数据成功:

更多推荐

mac 环境下 Scrapy 入门