爬虫scrapy框架简单爬取一个网页
爬虫scrapy框架
scrapy流程图

开始一个scrapy项目
首先进入你想要使用的虚拟环境,键入
pip install scrapy
下载完成后再虚拟环境中键入
scrapy startproject 项目名称

即可以在当前所在路径创建一个scrapy项目
创建一个爬虫文件
首先进入我们的scrapy项目
cd 项目名
这里我选择直接用命令行生成爬虫文件
scrapy genspider 爬虫名 爬虫网页路径

现在我们新建了了一个爬虫文件
测试这个爬虫能不能爬到数据
同样的,我们可以用scrapy框架测试我们的项目
scrapy shell 爬虫网页路径

建立链接后键入
response.text

这里证明我们的链接可以获取到网页数据了
修改parse方法
现在我们回到pycharm中,看一下我们创建到的项目结构

版本原因可能有些scrapy版本不会自动创建middlewares,然后如果是python2.7的别忘记加utf-8编码格式
现在需要在项目中指定一下虚拟环境,这个和django差不多

现在我们的项目就不飘红了
我们在爬虫py文件中的parse方法中对返回到的值进行操作
先添加测试时候的代码
import scrapy
class Gw2metabuildSpider(scrapy.Spider):
name = 'GW2metabuild'
allowed_domains = ['metabattle.com']
start_urls = ['http://metabattle.com/']
def parse(self, response):
html_str=response.text
print(html_str)
在命令行中运行这个爬虫
scrapy crawl 爬虫名


这是获取到值的结果
现在我们需要对网页进行分析,得到我们需要的数据
首先我选的这个网页是我玩的游戏guildwar2的国外攻略网站,相对于国内的网页来说可能比较简单,如果同样方法爬国内网页可能不行,这时候我们需要去把settings中的字段变一下。这在之后的博客中会详细的讲一讲,我先把这个实例跑完
现在我换一下metabuild中的raid内容,把网页复制下来,然后写到我们的start_urls中,注意这个start_urls可以为多个值的,但这次只用一个。
import scrapy
class Gw2metabuildSpider(scrapy.Spider):
name = 'GW2metabuild'
allowed_domains = ['metabattle.com']
start_urls = ['https://metabattle.com/wiki/Raid']
def parse(self, response):
html_str=response.text
print(html_str)
重新在跑一次看看能不能获取到
现在,我需要在网页中拿下recommand职业的数据
这个网页其实比较简单,发送请求后的doc就是前端展示的完整网页了,所以只需要在element中通过xpath找到数据就可以直接在项目中用了

这里的recommand的xpath路径,我只取了其中职业类型的名字
//div[@class='build-card-c'][1]/div/div/div/span/a
我们在项目中测试一下找不找的到
修改代码为
import scrapy
class Gw2metabuildSpider(scrapy.Spider):
name = 'GW2metabuild'
allowed_domains = ['metabattle.com']
start_urls = ['https://metabattle.com/wiki/Raid']
def parse(self, response):
print('#############')
node_list=response.selector.xpath("//div[@class='build-card-c'][1]/div/div/div/span/a/text()").extract()
print(node_list)
重新跑一遍

找到了我们要的数据,这里是一个列表,逐条输出只要加个for遍历一下就可以了
修改item获取指定的字段
这里的item.py文件作用和django中的serializer有一定的相似之处,也是一个指定需要字段的方法
今天这部分还是没有详细的用到item的,所以只是简单的添加一条我们的职业名称,在item中加上一个filed就可以了

然后修改一下我们的爬虫,导入item并指定字段
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class Gw2Item(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
profession_name=scrapy.Field()
# -*- coding: utf-8 -*-
import scrapy
from GW2 import items
class Gw2metabuildSpider(scrapy.Spider):
name = 'GW2metabuild'
allowed_domains = ['metabattle.com']
start_urls = ['https://metabattle.com/wiki/Raid']
def parse(self, response):
print('#############')
node_list=response.selector.xpath("//div[@class='build-card-c'][1]/div/div/div/span/a/text()").extract()
print(node_list)
item_list = []
for i in node_list:
item=items.Gw2Item()
item['profession_name']=i
item_list.append(item)
return item_list
这里代码有点冗余,毕竟我之找了一个字段信息,如果是多个字段就不能这样写了,现在我们把这个数据保存成csv文件,只需要在环境下键入
scrapy crawl 爬虫名 -o 文件名.csv
即可,结果如图

链接数据库
现在我们来改pipelines中的内容
import pymongo
class Gw2Pipeline(object):
def __init__(self):
self.client=pymongo.MongoClient(host='localhost',port=27017)
self.db=self.client['GW2_raid_metabuild']
def process_item(self, item, spider):
self.db.profession_name.insert(item)
print('enter process_item ##########')
return item
关于pipeline类,我们可以创建无数个pipeline类,但是每个pipelines类必须实现一个process_item方法,这个方法会自动返回一个item,这个返回值是用来给下一个pipeline类进行数据筛选的。
为了链接数据库,我们可以在调用类的时候进行链接,也可以在爬虫开始的时候进行链接,我这里是调用类的时候链接,如果想要在爬虫开始的时候链接,我们可以在下面这个方法中添加数据库的链接
这个是pipeline类中的方法
def open_spider(self,spider):
二级链接
为了获取从开始的页面中包含的url信息并给这个url发送信息,我们需要用到scrapy.Request方法
改写我们的爬虫文件为
# -*- coding: utf-8 -*-
import scrapy
from GW2 import items
class Gw2metabuildSpider(scrapy.Spider):
name = 'GW2metabuild'
allowed_domains = ['metabattle.com']
start_urls = ['https://metabattle.com/wiki/Raid']
def parse(self, response):
这里获取了一个网页中包含的url信息
href=response.selector.xpath('//*[@id="mw-content-text"]/div/div[3]/div[1]/div[1]/div[2]/span/a/@href').extract_first()
将url拼接成可以使用的完整的url
url='https://'+self.allowed_domains[0]+href
往items中添加字段,注意要在items.py中注册这个字段
item=items.Gw2Item()
item['second_url']=url
往新的链接发送请求
yield scrapy.Request(url=url,meta={'meta':item},callback=self.Zerksite)
新页面处理函数
def Zerksite(self,response):
拿出其中的部分内容
overview=response.selector.xpath('//*[@id="mw-content-text"]/div/dl/dd/text()').extract()
print(overview)
将之前Request方法中传递的item类取出
item=response.meta['meta']
将新的字段添加到item,同样的,需要在items.py中注册字段
item['overview']=overview
print(item)
抛出item
yield item
修改我们的pipelines
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import pymongo
class Gw2Pipeline(object):
def __init__(self):
self.client=pymongo.MongoClient(host='localhost',port=27017)
self.db=self.client['GW2_raid_metabuild']
def process_item(self, item, spider):
self.db.overview.insert(dict(item))
print('enter process_item ##########')
return item
现在跑一次crawl

查看数据库

获取成功
scrapy-redis分布爬虫

