文章目录
- 安装
- 步骤
- 新建爬虫项目 - 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对象作为唯一参数,用来- 解析返回的网页数据(response.body)
- 提取结构化数据(生成item)
- 生成需要下一页的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 入门
发布评论