目录结构:
|写在前面:
|依葫芦画瓢:
| | 安装:
| | 概述:
| | 创建一个scrapy项目
| | 第一个scrapy蜘蛛
| | 运行蜘蛛
| | scrapy调试工具
| | css提取工具的用法(初)
|详解Scrapy
| | 如何打开页面?
| | 如何提取数据?
| | css选择器提取数据
| | | 标签属性值提取
| | | 标签内容提取
| | | 标签嵌套
| | xpath选择器提取数据
| | | 标签属性值提取
| | | 标签内容提取
| | | 标签嵌套
| | scrapy命令行工具
| | |全局命令
| | |项目命令
写在前面:
最近公司因业务需求,需要爬取网络上一些兼职开发人员的简历信息。临危受命,便开始了爬虫之路。(Ps:下一篇文章将介绍爬取的记录,敬请关注)其实,爬虫在大二上的时候杨凌云老师有讲过这门课,只可惜那时候痴迷于Java,没怎么花心思在爬虫上面。(Ps:杨老师请收起你那40米长大刀^0^)之前大家都说爬虫很简单的只需要一点python基础就行了。好吧,pyhton基础还是有一点的,毕竟在大一下张荣臻老师还是有印象的。和我学习其它新东西一样,一切从0开始循序渐进,找了个好的教程,对照着它一步步学习,到现在发现爬虫还是挺简单的,网页上大部分数据还是能轻松爬取得到。就目前而言,已经足够了,毕竟选择了Java重点还是以Java为主,现在有接触需要用到爬虫,那就索性花点时间来丰富自己的技术栈吧。本文重点不会很深入去展开说里面的细节实现,只是带着学习过之后再回过头看看做个记录再理解理解有个印象,下次有需要稍微看一下,便能立马使用为出发点。http://www.scrapyd.cn/doc/我学习的网站,讲的还是挺不错的。稍微看个2-3天就差不多就能熟练应用了。起初,我也没啥太大自信觉得太难了,自己学不会,但后来发现是我多余了,仔仔细细多读几次,自己亲手把里面介绍的方法多敲一敲就会了。加油!相信自己!
依葫芦画瓢:
安装
Python、anaconda、pycharm、TensorFlow之间的关系及安装捷径
https://blog.csdn.net/huiyanfei/article/details/80175780
anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。因此,无需单独安装Python,直接安装一个anaconda就拥有了包含Python的开发包。
Ps:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/
清华大学开源软件镜像站,下载速度快一点。建议从这里下载。
PyCharm是一种Python IDE。类似于Java的Idea。
先安装anaconda,然后安装pycharm,在pycharm中将项目的Python运行环境设置为anaconda安装路径中的Python。
概述
scrapy是一个网页爬虫框架。
扩展阅读:
cola一个分布式爬虫框架。
PySpider国人编写的强大的网络爬虫系统并带有强大的WebUI。
创建一个scrapy项目
【scrapy startproject qwe】
选取一个文件夹在CMD中创建一个叫qwe的项目,然后再pychram中打开即可。
第一个scrapy蜘蛛
import scrapy
class My_First_Spider(scrapy.Spider):
name = "SpiderName" #定义一个蜘蛛名字
#用简化的方法,我们必须定义一个方法为:def parse(self, response),方法名一定是:parse
#简化start_requests(self)
start_urls = [ # 另外一种写法,无需定义start_requests方法
'http://lab.scrapyd.cn/page/1/',
'http://lab.scrapyd.cn/page/2/',
]
def start_requests(self): # 由此方法通过下面链接爬取页面
# 定义爬取的链接
urls = [
'http://lab.scrapyd.cn/page/1/',
'http://lab.scrapyd.cn/page/2/',
]
for url in urls:
yield scrapy.Request(url=url, callback=self.parse) # 爬取到的页面如何处理?提交给parse方法处理
def parse(self, response):
'''
start_requests已经爬取到页面,那如何提取我们想要的内容呢?那就可以在这个方法里面定义。
这里的话,并木有定义,只是简单的把页面做了一个保存,并没有涉及提取我们想要的数据,后面会慢慢说到
也就是用xpath、正则、或是css进行相应提取,这个例子就是让你看看scrapy运行的流程:
1、定义链接;
2、通过链接爬取(下载)页面;
3、定义规则,然后提取数据;
就是这么个流程,似不似很简单呀?
'''
page = response.url.split("/")[-2] #根据上面的链接提取分页,如:/page/1/,提取到的就是:1
filename = 'mingyan-%s.html' % page #拼接文件名,如果是第一页,最终文件名便是:mingyan-1.html
with open(filename, 'wb') as f: #python文件操作,不多说了;
f.write(response.body) #刚才下载的页面去哪里了?response.body就代表了刚才下载的页面!
self.log('保存文件: %s' % filename) # 打个日志
运行蜘蛛
【scrapy crawl 蜘蛛名】
①运行蜘蛛crawl后面跟的是你类里面定义的蜘蛛名,也就是:name ="SpiderName"
②一定要进入:qwe这个目录,也就是我们创建的蜘蛛项目目录,以上命令才有效!
③运行发现报SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xd2 in position 23: invalid continuation byte错误。在你刚才创建的python文件最头上加上# -*-coding:GBK -*-OK,再运行一切正常。
scrapy调试工具
【scrapy shell你要爬取的网址】调试(提取)数据
scrapy提取数据的几种方式:CSS、XPATH、RE(正则) |
自己敲一敲 就知有木有!那个学习的网站给出的例子。
css提取工具的用法(初)
response.css('标签名'),标签名的话可以是html标签比如:title、body、div,也可以是你自定义的class标签。
In [1]: response.css('title')
Out[1]: [<Selector xpath='descendant-or-self::title' data='<title>程序员兼职,程序员远程私活平台-程序员客栈</title>'>]
extract()函数提取我们标签的一个列表
In [2]: response.css('title').extract()
Out[2]: ['<title>程序员兼职,程序员远程私活平台-程序员客栈</title>']
extract()[0] & extract_first()提取这个列表中的第一个元素
In [3]: response.css('title').extract()[0] Out[3]: '<title>程序员兼职,程序员远程私活平台-程序员客栈</title> In [4]: response.css('title').extract_first() Out[4]: '<title>程序员兼职,程序员远程私活平台-程序员客栈</title> |
::text提取标签里面的数据
In [7]: response.css('title::text').extract() Out[7]: ['程序员兼职,程序员远程私活平台-程序员客栈']
In [8]: response.css('title::text').extract()[0] Out[8]: '程序员兼职,程序员远程私活平台-程序员客栈'
In [9]: response.css('title::text').extract_first() Out[9]: '程序员兼职,程序员远程私活平台-程序员客栈' |
提取一组数据
每一段名言都被一个 <div class="quote post">……</div> 包裹。
提取的是第一段名言里面的数据,然后保存在mingyan1变量里面,再进一步提取里面的以上数据。
mingyan1 = response.css('div.quote')[0]
[0] 这表示提取第一段,如果没有这个限制,那我们提取的是本页所有名言。
text = mingyang1.css('.text::text').extract()[0] # 提取名言
autor = mingyang1.css('.author::text').extract()[0] # 提取作者
tags = mingyang1.css('.tag::text').extract() # 提取标签
tags = ','.join(tags) # 数组转换为字符串
scrapy 列表爬取
递归调用
mingyan = response.css('div.quote') # 提取首页所有名言,保存至变量mingyan
# mingyan 这个数据集里面的数据,循环赋值给:v 第一次循环的话 v 就代表第一条数据
for v in mingyan: # 循环获取每一条名言里面的:名言内容、作者、标签
text = v.css('.text::text').extract_first() # 提取名言
autor = v.css('.author::text').extract_first() # 提取作者
tags = v.css('.tags .tag::text').extract() # 提取标签
tags = ','.join(tags) # 数组转换为字符串
fileName = '%s-语录.txt' % autor # 定义文件名,如:木心-语录.txt
# 接下来,进行保存
with open(fileName, "a+") as f: # 不同人的名言保存在不同的txt文档,“a+”以追加的形式
f.write(text)
f.write('\n') # ‘\n’ 表示换行
f.write('标签:' + tags)
f.write('\n-------\n')
f.close()
全站爬取
重点:如何把链接提交给本方法或是另一个方法,进行进一步爬取!
提取属性 标签名::attr(属性名)----> <a href="http://lab.scrapyd.cn/page/1/"> |
next_page = response.css('li.next a::attr(href)').extract_first()
if next_page is not None:
next_page = response.urljoin(next_page)
#如果存在的话,我们使用:response.urljoin(next_page)把相对路径,
#如:page/1转换为绝对路径。其实也就是加上网站域名,如:http://lab.scrapyd.cn/page/1;
yield scrapy.Request(next_page, callback=self.parse)
#①:我们继续爬取的链接(next_page),这里是下一页链接,当然也可以是内容页。
#②:我们要把链接提交给哪一个函数爬取,这里是parse函数,也就是本函数。
指定蜘蛛参数爬取
【scrapy crawl argsSpider -a tag=标签名】指定蜘蛛参数爬取
def start_requests(self):
url = 'http://lab.scrapyd.cn/'
tag = getattr(self, 'tag', None) # 获取tag值,也就是爬取时传过来的参数
if tag is not None: # 判断是否存在tag,若存在,重新构造url
url = url + 'tag/' + tag #构造url若tag=爱情,url= "http://lab.scrapyd.cn/tag/爱情"
yield scrapy.Request(url, self.parse) # 发送请求爬取参数内容
详解Scrapy
如何打开页面?
一种作为类的常量
start_urls = [ #另外一种写法,无需定义start_requests方法
'http://lab.scrapyd.cn/page/1/',
'http://lab.scrapyd.cn/page/2/',
]
一种作为start_requests(self)方法的常量
def start_requests(self): # 由此方法通过下面链接爬取页面
#定义爬取的链接
urls = [
'http://lab.scrapyd.cn/page/1/',
'http://lab.scrapyd.cn/page/2/',
]
for url in urls:
#发送请求
#爬取到的页面如何处理?提交给parse方法处理
yield scrapy.Request(url=url, callback=self.parse)
scrapy.Request方法发送请求请求页面
def parse(self,response):返回页面
如何提取数据?
----css选择器提取数据
1.标签属性值提取 |
标签名::attr(属性名)
找到我们要提取目标最近的class或是id。代码中有个class="page-navigator"
response.css(".page-navigator a::attr(href)").extract()
In [23]: response.css("ol.page-navigator a::attr(href)").extract()[0]
Out[23]: 'http://lab.scrapyd.cn/page/1/'
In [24]: response.css("ol.page-navigator a::attr(href)").extract()
Out[24]:
['http://lab.scrapyd.cn/page/1/',
'http://lab.scrapyd.cn/page/2/',
'http://lab.scrapyd.cn/page/3/',
'http://lab.scrapyd.cn/page/4/',
'http://lab.scrapyd.cn/page/6/',
'http://lab.scrapyd.cn/page/2/']
.点代表class选择器,如果代码中是:id=“page-navigator”,那我们这里就要写成#page-navigator
2.标签内容提取 |
::text
In [4]: response.css("title::text").extract()[0]
Out[4]: '泰戈尔 - SCRAPY爬虫实验室 - SCRAPY中文网提供'
3.标签嵌套 |
*::text()
最常用的提取方式:含有嵌套标签文字的提取
<div itemprop="articleBody">
<p>如果你因失去了太阳而流泪,那么你也将失去群星了。<br>
If you shed tears when you miss the sun, you also miss the stars.
</p>
<p>
<a href="http://www.scrapyd.cn">scrapy中文网(</a><a href="http://www.scrapyd.cn">http://www.scrapyd.cn</a>)整理
</p>
</div>
response.css(".post-content *::text")
::text前面有个“*”号,这是一个小技巧
-----xpath选择器提取数据
1.标签属性值提取 |
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
@ 选取属性。
限定范围:标签[@属性名='属性值']
In [10]: response.xpath("//ol[@class='page-navigator']//@href")
Out[10]:
[<Selector xpath="//ol[@class='page-navigator']//@href" data='http://lab.scrapyd
.cn/page/1/'>,
<Selector xpath="//ol[@class='page-navigator']//@href" data='http://lab.scrapyd
.cn/page/2/'>,
<Selector xpath="//ol[@class='page-navigator']//@href" data='http://lab.scrapyd
.cn/page/3/'>,
<Selector xpath="//ol[@class='page-navigator']//@href" data='http://lab.scrapyd
.cn/page/4/'>,
<Selector xpath="//ol[@class='page-navigator']//@href" data='http://lab.scrapyd
.cn/page/6/'>,
<Selector xpath="//ol[@class='page-navigator']//@href" data='http://lab.scrapyd
.cn/page/2/'>]
2.标签内容提取 |
//text()
In [4]: response.xpath("//title//text()").extract()
Out[4]: ['SCRAPY爬虫实验室 - SCRAPY中文网提供']
In [5]: response.xpath("//ul[@class='tags-list']//a//text()").extract()
Out[5]:
['\r\n 人生',
'\r\n 励志',
'\r\n 爱情',
'\r\n 王尔德',
'\r\n 智慧',
'\r\n 泰戈尔',
'\r\n 绝世好词',
'\r\n 木心',
'\r\n 艺术',
'\r\n 名画',
'\r\n 生活',
'\r\n 词',
'返回首页',
'SCRAPY中文社区',
'SCRAPY中文网']
3.标签嵌套 |
string(要提取内容的标签)
主要是提取一些内容页,里面标签夹杂着文字,但我们只要文字!
<div itemprop="articleBody">
<p>如果你因失去了太阳而流泪,那么你也将失去群星了。
<br>If you shed tears when you miss the sun, you also miss the stars.
</p>
<p><a href="http://www.scrapyd.cn">scrapy中文网(</a><a href="http://www.scrapyd.cn">http://www.scrapyd.cn</a>)整理</p>
</div>
response.xpath("string(//div[@class='post-content'])").extract()
scrapy命令行工具
*scrapy deploy scrapy1.0之后这个命令就被独立成了一个模块。部署命令。
----全局命令
在哪都能用
【startproject】
【genspider】创建蜘蛛模板
scrapy genspider 蜘蛛名 要爬取地址
【settings】
scrapy settings --get DOWNLOAD_DELAY 蜘蛛的下载延迟
scrapy settings --get BOT_NAME 获取蜘蛛名
【runspider】
scrapy runspider My_First_Spider.py 按照scrapy的蜘蛛格式编写了一个py文件(无需创建项目) 即可运行
【shell】
【fetch】
scrapy fetch http://www.scrapyd.cn >d:/3.html
把它的html代码拿下来看看,到底有木有我们想要的那个标签节点,如果木有的话,你就要明白我们需要使用js渲染之类的技术!
----项目命令
只能依托你的项目 需要在项目文件夹下面打开CMD命令
scrapy crawl 蜘蛛名 运行蜘蛛
scrapy check 检查蜘蛛
scrapy list 显示有多少个蜘蛛