Scrapy简介
Scrapy,Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等,最新版本又提供了web2.0爬虫的支持。
Scrapy项目结构
scrapy.cfg: 项目的配置文件
lianjia/: 该项目的python模块。之后您将在此加入代码。
lianjia/items.py: 项目中的item文件.
lianjia/pipelines.py: 项目中的pipelines文件.
lianjia/settings.py: 项目的设置文件.
lianjia/spiders/: 放置spider代码的目录.
下面主要说一下几个比较重要的:
**item.py**
Item 是保存爬取到的数据的容器。比如我下面将要爬取的链家网租房信息的地点、平米数、价格,我会在item.py
文件中定义相应的字段。
from scrapy import Item,Field
class LianjiaItem(Item):
# define the fields for your item here like:
# name = scrapy.Field()
place=Field() #爬取链家租房信息的-地点
size=Field() #爬取链家租房信息的-房屋平米数
price = Field() # 爬取链家租房信息的-价格
**spider.py**
此文件是我们在spiders文件下自己创建的,用来写爬虫的代码的,非常重要。
我们需要创建一个Spider,必须继承scrapy.Spider
,并有下面三个属性:
**name:** 用于区别Spider。 该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。
**start_urls:** 包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。
**parse()** 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。
**pipelines.py**
主要作用是为爬取下的数据的做处理。比如txt或者存入数据库的操作。
**settings.py**
主要是对爬虫项目的设置
Scrapy框架爬虫实战
今天主要爬取一下链家网租房主页的前一百页数据,也是为了带大家去入门熟悉一下Scrapy框架。
创建项目
命令行切换到你想创建Scrapy项目的路径,我是在D盘pycharm文件夹创建的
输入:
代码语言:txt复制scrapy startproject 项目名称
然后我们用PyCharm导入:File-->Open
爬取链家网详解
1.编写item.py
,定义爬取的字段。我们爬取链家网条目的租房地点、平米数以及价位,所以定义三个字段,代码如下:
from scrapy import Item,Field
class LianjiaItem(Item):
# define the fields for your item here like:
# name = scrapy.Field()
place=Field() #爬取链家租房信息的-地点
size=Field() #爬取链家租房信息的-房屋平米数
price = Field() # 爬取链家租房信息的-价格
pass
2.在spiders文件夹下创建spider.py
,用来爬取代码。代码如下:
import scrapy
from scrapy.http import Request
from lianjia.items import LianjiaItem
class LianjiaSpider(scrapy.Spider):#必须继承scrapy.Spide
name = "lianjia" #名称
start_urls = ['https://tj.lianjia.com/zufang/'] #URL列表
def parse(self, response):
item=LianjiaItem()
infos=response.xpath('//div[@class="info-panel"]')
for info in infos:
# 获取地点
place = info.xpath('div/div/a[@class="laisuzhou"]/span/text()').extract()[0].replace('xa0','')
# 获取平米数
size = info.xpath('div/div/span[@class="meters"]/text()').extract()[0].replace('xa0','')
# 获取价格
price = info.xpath('div/div[@class="price"]/span/text()').extract()[0] info.xpath(
'div/div[@class="price"]/text()').extract()[0]
item['place']=place
item['size'] = size
item['price'] = price
yield item #返回数据
#从新设置URL,从第2页到第100页 回调parse方法
for i in range(2,101):
url = 'https://tj.lianjia.com/zufang/pg{}/'.format(str(i))
yield Request(url, callback=self.parse) ## 回调
通过代码我们会发现,Item字段是通过Selector选择器提取的。
它有四个基本的方法:
**xpath():** 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表 。
**css():** 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表.
**extract(): **序列化该节点为unicode字符串并返回list。
**re():** 根据传入的正则表达式对数据进行提取,返回unicode字符串list列表。
另外也可以在Shell中调试xpath等,具体的操作在下面,慢慢看。
3.txt形式存储
pipelines.py
就是对爬取下的数据做处理的,所以我们可以在此文件中写txt或者数据库存储等等,今天就以TXT存储为例:
class LianjiaPipeline(object):
def process_item(self, item, spider):
try:
place = str(item['place'])
size = str(item['size'])
price = str(item['price'])
fb = open("C:/Users/qzs/Desktop/qinzishuai.txt", "a ")
fb.write(place size price 'n')
fb.close()
except:
pass
return item
另外还需要在settings.py
中配置一下,名称一定要换成你的项目名称:
ITEM_PIPELINES = {
'lianjia.pipelines.LianjiaPipeline': 300, #保存到txt文件
}
4.运行
运行scrapy项目两种方式:
(1).在Terminal输入命令运行,也就是在项目路径的命令行输入:
代码语言:txt复制scrapy crawl 项目名称
(2).在Pycharm中运行。我们要在scrapy.cfg
同层目录下建一个begin.py
文件,输入代码:
from scrapy import cmdline
cmdline.execute("scrapy crawl lianjia".split())
然后再点击Run-->Edit Configurations...
然后我们就可以运行了。
**强调:**第一次运行的时候,我遇到no module named win32API错误,这是因为Python没有自带访问windows系统API的库的,需要下载第三方库。
直接在pip安装即可:
代码语言:txt复制pip install pypiwin32
安装完成后运行成功,查看TXT:
Scrapy Shell调试xpath
快捷命令:
shelp() - 打印可用对象及快捷命令的帮助列表
fetch(request_or_url) - 根据给定的请求(request)或URL获取一个新的response,并更新相关的对象
view(response) - 在本机的浏览器打开给定的response。 其会在response的body中添加一个 <base> tag ,使得外部链接(例如图片及css)能正确显示。 注意,该操作会在本地创建一个临时文件,且该文件不会被自动删除。
在命令行输入:
代码语言:txt复制scrapy shell "爬取的URL"
然后会显示你能内容如下,说明成功进入shell:
下面主要说一下response.xpath调试,为了判断我们的xpath是否正确。
例如我们想调试一下链家网租房的地点信息,输入:
代码语言:txt复制response.xpath('//div/div/a[@class="laisuzhou"]/span/text()').extract()
结果显示:
说明我们的xpath没有问题。
再可以输入:
代码语言:txt复制view.(response)
效果如下:
****
希望对大家有所帮助!