本文正在参加「Python主题月」,详情查看 活动链接
Scrapy 是一套基于Twisted的异步处理框架,纯python实现的爬虫框架,只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非常方便~
由于工作中需要用到爬虫技术,就学习了一下scrapy,发现还挺好用的,而且非常适合于爬虫新上手的同学,下面我们就一起来了解一下吧
安装
win安装
安装pywin32
- 进入sourceforge.net/projects/py…或者github.com/mhammond/py…下载python对应的pywin32包
- 傻瓜式安装
- 检查安装结果,python命令行输入
import win32api,如果没有报错,安装成功
安装Twisted
- 进入www.lfd.uci.edu/~gohlke/pyt…,下载对应twisted和lxml
pip install ******.whl(没有安装pip,点击查看安装方法)- 输入命令
pip --version检查是否安装成功
安装scrapy
命令行输入:pip install scrapy
scrapy 框架学习
框架架构图
目录结构
- items.py 存放爬取的数据模型
- middwares.py 中间件
- pipelines.py 把爬取的数据保存
- settings.py 爬虫的配置信息
- scrapy.cfg 项目的配置文件
- spiders目录 爬虫脚本
基本使用
1.新建一个项目
scrapy startproject 项目名字
2.scrapy.cfg 打包部署文件
3.创建爬虫
scrapy genspider 爬虫名字 网站域名
4.注意:
- 爬虫名字不能和项目名字一样
- 网站域名
5.爬虫文件所在位置
项目名/项目名/spiders/爬虫名字.py
6.查看scrapy有几个类
scrapy genspider -l
7.selectors选择器
- 正则
- Xpath表达式
- css
8.Xpath表达式规则
demo
# html代码
<title>我是标题</title>
# 获取title内容
# title是html标签
# text获取内容
# extract
reponse.xpath('//title/text()').get();
9.运行爬虫
scrapy crawl 爬虫名
10.运行爬虫并保存结果
scrapy crawl 爬虫名 -o xxx.csv(或者xxx.json)
11.拼接url
reponse.urljoin(uri)
12.分页
yield scrapy.Request(url, callback=self.parse)
采取管道方式存储数据
在settings.py中开启
# 300 表示优先级 越小优先级越高
ITEM_PIPELINES = {
'cxianshengSpider.pipelines.CxianshengspiderPipeline': 300,
}
管道中采取json方式纯存储数据,以导入的方式存储
# 批量存入 适合数据量小的场景
from scrapy.exporters import JsonItemExporter
# 一行一行存入 数据量大的时候使用
from scrapy.exporters import JsonLinesItemExporter
用法:
# 定义
self.exporter = JsonItemExporter(self.fp, ensure_ascii=False, encoding='utf-8')
# 使用
self.exporter.export_item(item)
CrawlSpider
crawlSpider可以创建更灵活的爬虫,可以自定义爬取规则等
创建crawl爬虫
scrapy genspider -t crawl 爬虫名 域名
最新请求头地址
useragentstring.com/pages/usera…
设置下载器中间件
1.在middlewares.py增加如下代码:
import random
class HttpbinUserAgentMiddleware(object):
user_agent = [
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
"Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]
def process_request(self,request,spider):
# 随机获取一个请求头
user_agent = random.choice(self.user_agent)
# 设置请求头user-agent
request.headers['User-Agent'] = user_agent
2.settings.py开启:
# HttpbinUserAgentMiddleware为自己设置的下载器类的名称
DOWNLOADER_MIDDLEWARES = {
'httpBin.middlewares.HttpbinUserAgentMiddleware': 543,
}
并开启下载请求间隔时间
# 3表示3秒
DOWNLOAD_DELAY = 3
3.爬虫代码
# -*- coding: utf-8 -*-
import scrapy
import json
class UseragentdemoSpider(scrapy.Spider):
name = 'userAgentDemo'
allowed_domains = ['httpbin.org']
start_urls = ['http://httpbin.org/user-agent']
def parse(self, response):
data = json.loads(response.text)['user-agent']
print('='*30)
print(data)
print('='*30)
# 重复发起请求
yield scrapy.Request(self.start_urls[0], dont_filter=True)
pass
Xpath规则学习
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<a class="a-test" href="/next/2" >email me</a>
</body>
</html>
Xpath表达式
基本使用
- text获取内容
@定位符
表达式
1.获取指定标签的内容
//title/text()
2.根据html属性定位获取内容 @定位符
获取a标签href内容
//a[@class="a-text"]/@href
scrapy配合Xpath
代码示例:(PS:这里的例子为本人的博客,亲测有效:
# -*- coding: utf-8 -*-
import scrapy
class CxianshengSpider(scrapy.Spider):
name = 'cxiansheng' # 爬虫名称
allowed_domains = ['cxiansheng.cn'] # 允许爬取的域名
start_urls = ['https://cxiansheng.cn/'] # 开始爬取的url
def return_default_str(self, str):
return str.strip() if str else ''
def parse(self, response):
selectors = response.xpath('//section/article')
for selector in selectors:
article_title = selector.xpath('./header/h1/a/text()').get()
article_url = selector.xpath('./div/p[@class="more"]/a/@href').get()
article_title = self.return_default_str(article_title)
article_url = self.return_default_str(article_url)
yield {'文章标题': article_title, '文章地址': article_url}
next_url = response.xpath('//nav[@class="pagination"]/a[@class="extend next"]/@href').get()
if next_url:
# 重新发起请求
yield scrapy.Request(next_url, callback=self.parse)
爬完让我知道了一个事实,我的博客写的并不多,哭/(ㄒoㄒ)/~~
源码地址: Python scrapy demo