Python的创世人是吉多·范罗苏姆。1989年圣诞节期间,吉多为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序作为ABC语言的一种继承。ABC是由吉多参加设计的一种教学语言。就吉多本人看来,ABC这种语言非常优美和强大,是专门为非专业程序员设计的。但是ABC语言并没有成功,究其原因,吉多认为是非开放造成的。吉多决心在Python中避免这一错误,并获取了非常好的效果,完美结合了C和其他一些语言,就这样,Python在吉多手中诞生了。
Python 特点
- 优点:简单、易学、速度快、免费、开源、高层语言、可移植、解释性、面向对象、可扩展、可嵌入、丰富的库、规范的代码
- 缺点:单行语句、运行速度慢、独特的语法(通过缩进区分语句关系)
Python应用
Python应用非常广泛,如系统编程、图形处理、数学处理、文本处理、数据库编程、网络编程、Web编程、多媒体应用、Pymo引擎、黑客编程、网络爬虫等,本篇文章就来学习一下Python的网络爬虫
Python爬虫框架
python爬虫框架有很多,如Scrapy、PySpider、Crawley、Portia、Newspaper、Beautiful Soup、Grab、Cola等,这么多框架不用学很多,学一个就可以,下面我们就来先学下一下比较热门的Scrapy框架
Scrapy框架
- 简介
Scrapy是一个用于以一种快速、简单、可扩展的方式从网站中提取所需要数据的开源框架。用途广泛,可以用于数据挖掘、监测和自动化测试。Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitema等
- 相关学习资料网址
scrapy官网:https://scrapy.org/
scrapy文档:https://docs.scrapy.org/en/latest/
github地址:https://github.com/scrapy/scrapy/
css选择器:http://www.w3school.com.cn/cssref/css_selectors.asp
xpath选择器:http://www.w3school.com.cn/xpath/index.asp
- 配置环境
首先需要配置Python3的环境,mac配置非常简单,只需要在终端执行命令brew install python3
,windows安装则需要到官网(http://www.python.org/download/)下载exe文件安装包, 然后再配置环境变量,这里就不多详细介绍。
Python环境配置好后,只需要在终端执行命令pip install scrapy
,这样Scrapy环境就已安装配置完成
- 项目搭建
在开始之前,建立一个新的Scrapy目录,进入到这个目录,并运行命令:
scrapy startproject helloScrapy
成功创建会有如下提示:
You can start your first spider with:
cd helloScrapy
scrapy genspider example example.com
这时就创建好了一个Scrapy项目, 可以按照这里的提示生成第一个spider, 第一个命令是进入到helloScrapy文件夹,第二个命令是生成模板,也就是在spiders文件夹下自动创建文件example.py。自动生成了name、allowed_domains、start_urls等属性和parse方法。name为spiders名,后面执行命令时只需要指定它就可以,allowed_domains为允许的域名访问,非该一级域名的网站都会被过滤掉,start_urls为开始爬取的网站url,该属性是一个数组可以为多个,parse方法为默认爬取到的所有数据回调,通过response对象接收,后面做处理都是通过response来搜索查询数据。简单说下项目的各个文件:
scrapy.cfg 为项目部署文件
items.py 为项目实体类文件
middlewares.py 为项目中间件文件
pipelines.py 为项目管道文件
settings.py 为项目设置配置文件
spiders文件夹用于存放Scrapy爬虫文件
example.py 是需要开发设计的爬虫文件
- 设计items.py
这个文件存放的是Scrapy爬虫项目自定义封装的实体对象,需要爬取的元素都在这个类里面申明,这里我们以(http://quotes.toscrape.com/tag/humor/)这个网站的数据来学习,设计item.py如下:
class HelloscrapyItem(scrapy.Item):
text = scrapy.Field()
author = scrapy.Field()
tags = scrapy.Field()
description = scrapy.Field()
pass
- 设计example.py
需要修改allowed_domains
、start_urls
和parse(self, response)
方法,并添加parse_author(self, response)
方法
# -*- coding: utf-8 -*-
import scrapy
from helloScrapy.items import HelloscrapyItem
class ExampleSpider(scrapy.Spider):
name = 'example'
allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/tag/humor/']
def parse(self, response):
for quote in response.css('div.quote'):
item = HelloscrapyItem()
#用strip()方法过滤开头的\r\n\t和空格符
item['text'] = quote.css('span.text::text').extract_first().strip()
item['author'] = quote.css('small.author::text').extract_first().strip()
item['tags'] = quote.css('div.tags a.tag::text').extract()
author_page = quote.css('small.author+a::attr(href)').extract_first()
yield scrapy.Request(url = response.urljoin(author_page), meta={'item': item}, callback=self.parse_author)
next_page = response.css('li.next a::attr("href")').extract_first()
if next_page is not None:
yield scrapy.Request(response.urljoin(next_page), callback=self.parse)
def parse_author(self, response):
item = response.meta['item']
item['description'] = {
'author_born_date': response.css('.author-born-date::text').extract_first().strip(),
'author_born_location': response.css('.author-born-location::text').extract_first().strip(),
'authro_description': response.css('.author-born-description::text').extract_first().strip(),
}
yield item
pass
parse
方法中response
参数是封装返回网页的所有数据,通过该参数对象可以获取任何你想要数据。
这里是通过css选择器来获取数据,也可以通过xpath选择器来获取,看个人喜好,不过推荐使用css选择器,它的语言简洁,运行速度更快。
通过浏览器的F12或对着网站上的数据鼠标右键检查,就可以定位到对应html代码区域,根据html代码可知,class=quote
的div有多个,分别对应每条数据的Item,每个div下面有详细数据,所以我们可以通过response.css('div.quote')
来获取到这一页面quote的数组列表,然后循环它,拿到里面的详细数据。例如我们要拿到author数据,可以看到quote div下面有一个class=author
的small标签,所以我们可以通过quote.css('span.text::text').extract_first().strip()
来获取数据,其中extract_first()
方法是获取到第一个符合的数据,strip()
方法是过滤过滤开头的\r\n\t和空格符。其它数据也是按照相同的方式去获取。
我们可以看到quote div下有一个about链接进入到关于页面,通过css选择器我们可以获得这个链接地址quote.css('small.author+a::attr(href)').extract_first()
,再通过response.urljoin(author_page)
补全地址信息,最后通过scrapy.Request
来发送一个请求,用parse_author
回调方法接收,从上面的代码可以看到传递了一个meta={'item': item}
,目的是为了拿到关于页面的数据存储到item中再返回回来,关于页面的数据也是一样通过css选择器获取,这里就不多做解释。
最后我们会发现有下一页,如何去拿下一页数据呢?其实也很简单。通过css选择器拿到下一页的地址response.css('li.next a::attr("href")').extract_first()
,然后判断存不存在下一页这个标签,表示有没有下一页,同样是通过scrapy.Request
发送请求,不过这里用自身parse
方法回调,因为逻辑代码都一样所以就直接可以调用自身。
简单在介绍下css选择器:
.quote
选择class=quote
的所有元素
#quote
选择id=quote
的所有元素
*
选择所有元素
div
选择<div>
的所有元素
div,p
选择所有<div>
元素和所有<p>
元素
div p
选择<div>
元素内部的所有<p>
元素
div>p
选择父元素为<div>
元素的所有<p>
元素
div+p
选择紧接在<div>
元素之后的所有<p>
元素
[title]
选择带有title
属性所有元素
[title=value]
选择title="value"
的所有元素
以上是简单的css选择器用法,更过用法可以在前面介绍的相关学习资料网站中查看
- 运行scrapy
crapy crawl example
通过上面命令代码执行即可。example是之前通过scrapy genspider example example.com
里的值,也可以在代码中修改name属性来更改这个值。只执行这个命令不会保存任何数据,如果需要保存数据到文件中,则需要执行命令来保存
crapy crawl example -o example.json
保存到example.json文件中, 这里保存的是json格式,还可以保存'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle'
这些文件格式。
- 设置请求头
很简单,只需要添加start_requests(self)
方法,去掉start_urls
属性,加上headers
属性。
headers = {
'User-Agent': "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
}
def start_requests(self):
url = 'http://quotes.toscrape.com/tag/humor/'
yield scrapy.Request(url, headers=self.headers, callback=self.parse)
这里header只添加了User-Agent,如果设置全局User-Agent的话可以再setting.py
中添加USER_AGENT = ''
即可。
- 设置代理Proxy
首先在setting.py
中添加PROXIES
属性:
PROXIES = [
'http://84.47.174.197:8080',
'http://13.232.75.24:80'
]
然后再middlewares.py
中添加ProxyMiddleware
类:
class ProxyMiddleware(object):
'''
设置Proxy
'''
def __init__(self, ip):
self.ip = ip
@classmethod
def from_crawler(cls, crawler):
return cls(ip=crawler.settings.get('PROXIES'))
def process_request(self, request, spider):
ip = random.choice(self.ip)
request.meta['proxy'] = ip
最后在setting.py
中开启,注意的是helloScrapy
是项目名
DOWNLOADER_MIDDLEWARES = {
'helloScrapy.middlewares.HttpbinProxyMiddleware': 543,
}
以上三步就可以实现代理请求了,如果PROXIES有多个,则会随机切换。很多网站都会有反爬虫机制,访问太频繁,ip会被拉入黑名单,所以设置代理就很有必要。
- 设置robots协议
在setting.py
中可以看到ROBOTSTXT_OBEY = True
,默认是True表示遵守robots.txt的规则。robots.txt 是遵循Robot协议的一个文件,它保存在网站的服务器中,它的作用是,告诉搜索引擎爬虫,本网站哪些目录下的网页不希望你进行爬取收录。在Scrapy启动后,会在第一时间访问网站的robots.txt 文件,然后决定该网站的爬取范围。所以某些时候,我们就要将此配置项设置为False,拒绝遵守Robot协议!
以上就是网络爬虫篇的全部内容,通过上面学习,大家可以爬取大部分的网站了。如果喜欢这篇文章的内容,可以关注我的个人公众号
Soaic
,第一时间获取相关文章~