【Python】Scrapy爬虫介绍requests爬虫移植到Scrapy爬虫
【Python】Scrapy爬虫介绍&&re爬虫移植到Scrapy爬虫
- Scrapy
- Scrapy爬虫框架
- requests和Scrapy对比
- Scrapy常用命令
- Scrapy 爬虫基本使用
- 第一个Scrapy实例
- Scrapy爬虫的基本使用
- Scrapy爬虫实例编写/re爬虫移植
- 豆瓣Top100爬虫
- 豆瓣Top100爬虫源re代码
- 环境配置参考
- 实例程序参考
- 程序编写
- 步骤1:建立工程
- 步骤2:建立Spider.模板
- 步骤3:编写 Spider
- 步骤4:配置并发连接选项,优化爬取速度:编写 Pipelines
- 爬取豆瓣top250的scrapy爬虫
- 参考
- douban.py
- pipelines处理数据,保存文件
- settings.py设置文件
- 运行爬虫
- 报错处理
- 修正后的`douban.py`版本/直接F12拷贝selector进行选择
Scrapy
Scrapy爬虫框架
Scrapy爬虫框架结构
爬虫框架
爬虫框架是实现爬虫功能的一个软件结构和功能组件集合。
爬虫框架是一个半成品,能够帮助用户实现专业网络爬虫。
五个主要模块,两个中间件。
Engine(不需要用户修改)
- 控制所有模块之间的数据流
- 根据条件触发事件
Downloader
- 根据请求下载网页
- 不需要用户修改
Scheduler
- 不需要用户修改
- 对所有爬取请求进行调度管理
Spider(最核心)
- 解析Downloader返回的响应(Response)
- 产生爬取项(Scraped item)
- 产生额外的爬取请求(Request)
Item Pipelines
- 以流水线处理Spider的爬取项
- 由一组操作顺序组成,类似一个流水线,每个操作是一个Item Pipeline类型。
- 可能操作包括:清理,检验和查重爬取项中的HTML数据,将数据保存到数据库。
中间件:Downloader Middleware
- 目的:实施 Engine、 Scheduler和 Downloader之间进行用户可配置的控制
功能:修改、丢弃、新增请求或响应
Spider Middleware
- 目的:对请求和爬取项的再处理
功能:修改、丢弃、新增请求或爬取项
用户可以编写配置代码
requests和Scrapy对比
Scrapy常用命令
Scrapy 爬虫基本使用
第一个Scrapy实例
DemoSpider这个类叫什么名字无所谓,只要他是继承于scrapy.Spider的子类即可。
parse()用于处理响应,解析内容形成字典,发现新的URL爬取请求。
产生步骤
- 步骤1:建立一个 Scrapy爬虫工程
- 步骤2:在工程中产生一个 Scrapy爬虫
- 步骤3:配置产生的 spider爬虫
- 步骤4:运行爬虫,获取网页。
cd pycodes
scrapy startproject python123demo
cd python123demo
scrapy genspider demo python123.io#生成一个名称为demo的spider,生成了demo.py
yield关键字。生成器。生成器是一个不断产生值的函数。
包含 yield语句的函数是一个生成器
生成器每次产生一个值( yield语句),函数被冻结,被唤醒后再产生一个值。
生成器,产生小于n的数的平方值。并将所有的返回值返回给上层调用函数。
普通写法:存储所有的数。
生成器写法:每次只要一个值。每次的存储空间是一个的存储空间。
当n很大时,生成器就有很大的优势。
Scrapy爬虫的基本使用
Scrapy爬虫的使用步骤
- 步骤1:刨建一个工程和 Spider模板
- 步骤2:编写 Spider
- 步骤3:编写 Item Pipeline
- 步骤4:优化配置策略
Scrap爬虫的数据类型
- Request类
- Response类
- Item类
Request类
class scrapy.http.Request()
Request对象表示ー个HTTP请求。
由 Spider生成,由 Downloader.执行。
Response类
class scrapy.http.Response()
Response对象表示一个HTTP响应。
由 Downloader生成,由 Spider处理。
Item类
class scrap.item.Item()
Item对象表示一个从HTML页面中提取的信息内容。
由 Spider生成,由 Item Pipelines处理。
爬取信息,封装成字典,存储。
Scrapy爬虫支持多种HTML信息提取方法
- Beautiful Soup
- lxml
- re
- Xpath Selector
- CSS Selector
Scrapy爬虫实例编写/re爬虫移植
豆瓣Top100爬虫
技术路线: scrapy
目标:获取上交所和深交所所有股票的名称和交易信息
输出:保存到文件中
豆瓣Top100爬虫源re代码
import re
import requests
from bs4 import BeautifulSoup
import xlwt
import time
def get_one_page(url):hd={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
}try:r = requests.get(url, timeout=30,headers=hd)r.raise_for_status()r.encoding = r.apparent_encodingreturn r.textexcept:return "geturl wrong!"def parser_one_page(s):s=re.sub('<br>',' ',s)s=re.sub(' ','',s)soup=BeautifulSoup(s,"html.parser")list=soup.find_all('div','item')for item in list: item_name = item.find(class_='title').stringitem_img = item.find('a').find('img').get('src')item_index = item.find(class_='').stringitem_score = item.find(class_='rating_num').stringitem_author = item.find('p').textif (item.find(class_='inq') != None):item_intr = item.find(class_='inq').stringprint('爬取电影:' + item_index + ' | ' + item_name +' | ' + item_img +' | ' + item_score +' | ' + item_author +' | ' + item_intr )#print('爬取电影:' + item_index + ' | ' + item_name + ' | ' + item_score + ' | ' + item_intr+' | '+item_img)global nsheet.write(n, 0, item_name)sheet.write(n, 1, item_img)sheet.write(n, 2, item_index)sheet.write(n, 3, item_score)sheet.write(n, 4, item_author)sheet.write(n, 5, item_intr)n = n + 1if __name__ == '__main__':book = xlwt.Workbook(encoding='utf-8', style_compression=0)sheet = book.add_sheet('豆瓣电影Top250', cell_overwrite_ok=True)sheet.write(0, 0, '名称')sheet.write(0, 1, '图片')sheet.write(0, 2, '排名')sheet.write(0, 3, '评分')sheet.write(0, 4, '作者')sheet.write(0, 5, '简介')n= 1urls=['https://movie.douban.com/top250?start={}&filter='.format(str(i)) for i in range(0,250,25)]for url in urls:html=get_one_page(url)parser_one_page(html)time.sleep(2)book.save(u'豆瓣最受欢迎的250部电影.csv')
环境配置参考
pycharm中创建scrapy项目
实例程序参考
import scrapyclass NewsSpider(scrapy.Spider):name = 'news'allowed_domains = ['hitwh.edu.cn']start_urls = ['http://today.hitwh.edu.cn/1024/list.htm']def decode(self,s):return bytes(s,encoding='utf-8')def parse(self, response):num = response.css(".all_pages ::text").extract()[0];for i in range(int(num)):try:url = "http://today.hitwh.edu.cn/1024/list"+str(i+1)+".htm"# print(url)yield scrapy.Request(url,callback=self.parse_pages)except:print("WRONG ON PAGE",str(i+1))continuedef parse_pages(self,response):# fname = "result.txt"# # print("unbegin")#with open(fname,"wb") as f:# total={}for item in response.css("#righ_list li"):url= "http://today.hitwh.edu.cn"+item.css("a ::attr(href)").extract()[0]yield scrapy.Request(url,callback=self.parse_detail)# total.update({"题目:":item.css("a ::text").extract()[0],# "时间":item.css("font ::text").extract()[2]})#print(item.css("a ::text").extract()[0]);# f.write(self.decode(item.css("a ::text").extract()[0]))# f.write(self.decode(item.css("font ::text").extract()[2]))# f.write(self.decode("\n")) # print(item.css("font ::text").extract()); # f.write(str(response.css("#righ_list a::text")))# self.log('Saved file %s.' % fname)def parse_detail(self,response):# fname = "result.txt"# # print("unbegin")#with open(fname,"wb") as f:total={}time = response.css(".newsNav ::text").extract()[2]time = time[6:-2]author = response.css(".newsNav ::text").extract()[0]author = author[5:-4]if (author==''):author="无"total.update({"题目":response.css(".newsTitle ::text").extract()[0],"时间":time,"作者":author})yield total# pipelines# 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# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import jsonclass HitwhPipeline:def process_item(self, item, spider):return item
class pagePipeline:def open_spider(self,spider):self.f = open("information.json","w",encoding='utf-8')def close_spider(self,spider):self.f.close()def process_item(self, item, spider):try:line=str(json.dumps(dict(item),ensure_ascii=False))+"\n"self.f.write(line)except Exception as e:print (str(e))print("ERROR")passreturn item
程序编写
步骤
步骤1:建立工程和 Spider模板
步骤2:编写 Spider
步骤3:编写 ITEM Pipelines
步骤1:建立工程
打开pycharm,自己在自己喜欢的路径下新建一个项目
步骤2:建立Spider.模板
scrapy startproject Web_scrapy
cd Web_scrapy
scrapy genspider douban movie.douban.com/top250
进一步修改 spiders/douban.py
文件
步骤3:编写 Spider
配置 douban.py
文件
修改对返回页面的处理
修改对新增URL爬取请求的处理
步骤4:配置并发连接选项,优化爬取速度:编写 Pipelines
配置
pipelines.py
文件
定义对爬取项( Scraped Item)的处理类
爬取豆瓣top250的scrapy爬虫
参考
Python yield 使用浅析
CSS – Python爬虫常用CSS选择器(Selectors)
爬虫Scrapy框架之css选择器使用
Scrapy:运行爬虫程序的方式
scrapy css选择器提取a标签内href属性值
douban.py
使用css选择器的方法是
选择href属性包含https://movie.douban.com/subject/
这个字符串的所有元素。
response.css("[href~=https://movie.douban.com/subject/]")
import scrapyclass DoubanSpider(scrapy.Spider):name = 'douban'allowed_domains = ['movie.douban.com/top250']start_urls = ['http://movie.douban.com/top250/']def decode(self,s):#设定以utf-8编码解析数据return bytes(s,encoding='utf-8')def parse(self, response):for i in range(25,225,25):try:url="http://movie.douban.com/top250?start="+str(i)yield scrapy.Request(url,callback=self.parse_pages)'''一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。'''except:print("wrong page",str(i))continuedef parse_pages(self,response):for item in response.css("[href~=https://movie.douban.com/subject/]"):#选择href属性包含字符串https://movie.douban.com/subject/的标签,实际上已经直接选中了a标签#for item in response.css(".hd")url=item.css("a::attr(href)").extract[0]yield scrapy.Request(url,callback=self.parse_detail)def parse_detail(self,response):total={}number=response.css(".top250-no::text").extract[0]name=response.css("div>h1::text").extract[0]year=response.css(".year::text").extract[0]#对year进行更为美观的处理,使用strip函数去掉开头和结尾的(和)year.strip("()")score=response.css(".ll rating_num::text").extract[0]total.update({"排名":number,"电影名":name,"上映年份":year,"电影评分":score})yield total
pipelines处理数据,保存文件
import jsonclass WebScrapyPipeline:def process_item(self, item, spider):return itemclass pagePipeline:def open_spider(self,spider):self.f=open("information.json","w",encoding='utf-8')def close_spider(self, spider):self.f.close()def process_item(self, item, spider):try:line = str(json.dumps(dict(item), ensure_ascii=False)) + "\n"self.f.write(line)except Exception as e:print(str(e))print("ERROR")passreturn item
settings.py设置文件
- 请求头
DEFAULT_REQUEST_HEADERS = {'User-Agent' : 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',#'Accept-Language': 'en',
}
- 管道
ITEM_PIPELINES = {'Web_scrapy.pipelines.WebScrapyPipeline': 300,'Web_scrapy.pipelines.pagePipeline':300
}
运行爬虫
示例一:全局运行
scrapy runspider <spider_file.py>
示例二:项目级运行
scrapy crawl <spider>
<spider>
是一个 爬虫程序的名称——爬虫类里面的name属性(必须required,且在项目中具有唯一性unique)。
报错处理
问题一:
cssselect.parser.SelectorSyntaxError: Expected ']', got <DELIM ':' at 12>
修改url池的提取:
for item in response.css("div.hd>a"):
问题二:
TypeError: 'method' object is not subscriptable
问题解决办法解释:
Python TypeError: ‘method’ object is not subscriptable Solution
#错误代码:
url=item.css("a::attr(href)").extract[0]#正确代码:
url=item.css("a::attr(href)").extract()[0]
问题三:
报错:
IndexError: list index out of range
参考解决:
IndexError: list index out of range and python
修正后的douban.py
版本/直接F12拷贝selector进行选择
直接在F12下copy对应标签的selector
import scrapyclass DoubanSpider(scrapy.Spider):name = 'douban'
# allowed_domains = ['movie.douban.com/top250']allowed_domains = ['movie.douban.com']start_urls = ['http://movie.douban.com/top250/']def decode(self,s):#设定以utf-8编码解析数据return bytes(s,encoding='utf-8')def parse(self, response):#爬取第一页url = "http://movie.douban.com/top250"yield scrapy.Request(url, callback=self.parse_pages)#爬取后面几页for i in range(25,250,25):try:url="http://movie.douban.com/top250?start="+str(i)yield scrapy.Request(url,callback=self.parse_pages)'''一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。'''except:print("wrong page",str(i))continuedef parse_pages(self,response):#选择href属性包含字符串https://movie.douban.com/subject/的标签,实际上已经直接选中了a标签#for item in response.css(".hd")for item in response.css("div.hd>a"):print(item)url=item.css("a::attr(href)").extract()[0]yield scrapy.Request(url,callback=self.parse_detail)def parse_detail(self,response):total={}number=response.css("span.top250-no::text").extract()[0]name=response.css("#content > h1 > span:nth-child(1)::text").extract()[0]year=response.css("#content > h1 > span.year::text").extract()[0]#对year进行更为美观的处理,使用strip函数去掉开头和结尾的(和)#year.strip("()")#year=year.replace('(','').replace(')','')score=response.css("#interest_sectl > div.rating_wrap.clearbox > div.rating_self.clearfix > strong::text").extract()total.update({"排名":number,"电影名":name,"上映年份":year,"电影评分":score})yield total
【Python】Scrapy爬虫介绍requests爬虫移植到Scrapy爬虫相关推荐
- python爬取小说章节信息用pygame进行数据显示_爬虫不过如此(python的Re 、Requests、BeautifulSoup 详细篇)...
网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本. 爬虫的本质就是一段自动抓取互联网信息的程序,从网络获取 ...
- python3 爬虫_Python3爬虫介绍
Python3爬虫介绍 一.为什么要做爬虫 首先请问:都说现在是"大数据时代",那数据从何而来? 数据管理咨询公司:麦肯锡.埃森哲.艾瑞咨询 爬取网络数据:如果需要的数据市场上没有 ...
- 数据分析利器Python——爬虫(含爬取过程、Scrapy框架介绍)
文章目录 一.基础知识 1.定义 2.基本架构 二.URL管理模块 三.网页下载模块 Python中的requests模块 四.网页解析模块 1.结构化网页解析 2.BeautifulSoup使用步骤 ...
- Python网络爬虫之requests库Scrapy爬虫比较
requests库Scrapy爬虫比较 相同点: 都可以进行页面请求和爬取,Python爬虫的两个重要技术路线 两者可用性都好,文档丰富,入门简单. 两者都没有处理JS,提交表单,应对验证码等功能(可 ...
- Python爬虫之scrapy框架介绍
一.什么是Scrapy? Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍.所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等) ...
- Python爬虫——scrapy框架介绍
一.什么是Scrapy? Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍.所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等) ...
- python scrapy框架爬虫_Scrapy爬虫框架教程(一)-- Scrapy入门
前言 转行做python程序员已经有三个月了,这三个月用Scrapy爬虫框架写了将近两百个爬虫,不能说精通了Scrapy,但是已经对Scrapy有了一定的熟悉.准备写一个系列的Scrapy爬虫教程,一 ...
- 0.爬虫介绍及requests库的使用
1. 互联网知识介绍 互联网: 是由网络设备(网线, 路由器, 交换机, 防火墙...)和一台台计算机链接而成. 互联网建立的目的: 数据的共享/传递. 俗称的'上网': 由用户端计算机发送请求给目标 ...
- 第063讲: 论一只爬虫的自我修养11:Scrapy框架之初窥门径 | 学习记录(小甲鱼零基础入门学习Python)
上一节课我们好不容易装好了 Scrapy,今天我们就来学习如何用好它,有些同学可能会有些疑惑,既然我们懂得了Python编写爬虫的技巧,那要这个所谓的爬虫框架又有什么用呢?其实啊,你懂得Python写 ...
- 《零基础入门学习Python》第063讲:论一只爬虫的自我修养11:Scrapy框架之初窥门径
上一节课我们好不容易装好了 Scrapy,今天我们就来学习如何用好它,有些同学可能会有些疑惑,既然我们懂得了Python编写爬虫的技巧,那要这个所谓的爬虫框架又有什么用呢?其实啊,你懂得Python写 ...
最新文章
- 洛谷 P3994 高速公路
- c语言中的运算符和表达式试卷答案,c语言试卷和答案1
- JQUERY拼接数组
- python中文文本分析_python使用snownlp进行中文文本处理以及分词和情感分析 - pytorch中文网...
- lua和unity如何交互_(XLua)C#与Lua中的交互
- 【2021牛客暑期多校训练营7】xay loves trees(dfs序,维护根出发的链)
- 对接支付宝遇到的坑sign check fail: check Sign and Data Fail
- AMD Catalyst 14.4 Linux带来完整的 OpenGL 4.4 支持
- atiitt it学科体系化 体系树与知识点概念大总结.xlsx
- 第03讲- 第一个Android项目
- android+cordova+windows打包vue一条龙服务
- IT行业发展凶猛,你的工作会被人工智能取代吗?
- Android——文件存储之外部存储
- 邮箱发送材料服务器连接错误,发送邮件常见的错误和解决方法
- 在苹果做了十年公关,我总结了这五条建议
- ResNet,GoogleNet的基本架构,与VGGNet,AlexNet等网络的对比和创新点。
- word整个表格首行缩进_Word2016中设置首行缩进的方法
- PMP章节练习—项目经理的角色
- 小学生长度、面积、时间、质量单位换算总结
- 【English】新征程,我们在路上
热门文章
- namecheap域名设置Cloudflare为第三方DNS
- 渗透测试-灰鸽子远控木马
- SICP 习题2.61~2.62 排序表示的adjoin和union-set函数
- 介绍ping中的TTL是什么意思
- Qt Cmake configuration has no path to a C++ compiler set, even though the toolkit has a v
- android常用快捷键大全,AndroidStudio 快捷键使用总结大全
- pause 和 title
- 清除tomcat缓存HTML,清除Tomcat缓存
- 密码学入门(7):数字签名和证书
- java工程名前有红色感叹号