当前位置: 首页 > 编程日记 > 正文

爬虫之Scrapy

Scrapy初步

Scrapy基于Twisted设计实现,Twisted的特殊特性是以事件驱动,并且对于异步的支持性很好,集成了高性能的异步下载,队列,分布式,持久化等。

Scrapy的安装

在Linux中可以直接在命令行中输入:pip install scrapy

在windows中:

- pip3 install wheel

- 下载twisted,http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

- 下载的Twisted一定要和自己当前python解释器的版本相匹配,不然不会报这个错误:

Twisted-18.9.0-cp37-cp37m-win_amd64.whl is not a supported wheel on this platform.

进入下载目录,执行 pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl

- pip3 install pywin32

- pip3 install scrapy

Scrapy的目录结构

使用 scrapy startproject projectname  启动项目。

- scrapy.cfg  scrapy项目的基础配置

- items.py  设置数据存储模板,用于结构化数据,如Django的Model

- middlewares.py  自己定义的中间件

- piplines  数据的持久化处理

- settings.py  配置文件,如:递归的层数、并发数、延迟下载等

- spiders  爬虫目录,创建文件,编写解析规则等

创建爬虫应用程序:

- 进入项目目录

- scrapy genspider 应用名称  爬取网页的起始url  (例如: scrapy genspider test_1 www.baidu.com)

- 会出现一个appname.py的文件,文件内容如下

import scrapyclass Test1Spider(scrapy.Spider):name = 'test_1'  #应用名allowed_domains = ['www.baidu.com']  #允许爬取的域名,如果非该域名的则跳过start_urls = ['http://www.baidu.com/']  #起始爬取的url#访问起始url并获取结果后的回调函数,该函数的response参数就是向起始的url发送请求后,获取的相应对象,
  该函数的返回值必须为可迭代对象获知NULL
def parse(self, response):pass  #response.text  获取字符串类型的相应内容
         #reponse.body  获取字节类型的相应内容

程序执行:

- scrapy crawl  爬虫名称

- scrapy crawl --nolog  #不显示执行的日志信息

案例一

修改settings.py文件

USER_AGENT="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360EE"
ROBOTSTXT_OBEY=False    #忽略君子协议

打开sprider文件

import scrapyclass QiuSprider(scrapy.Sprider):name="qiusp"allowed_domains=['https://www.qiushibaike.com/']start_urls=['https://www.qiushibaike.com/']def parse(self,response):#xpath为response函数的方法odiv=response.xpath('//div[@id="content-left"]/div')content_list=[]    #存储解析数据for div in odiv:#xpath函数返回列表,列表中的数据为selector类型,需要调用extract()函数取出数据
       author = div.xpath('.//div[@class="author clearfix"]/a/h2/text()')[0].extract()
       content=div.xpath('.//div[@class="content"]/span/text()')[0].extract()
       #将解析内容封装到字典中
       dic={ '作者':author, '内容':content }
       #将数据存到content_list中
       content_list.append(dic)
     return content_list

案例二

spider

import scrapyfrom bossPro.items import BossproItem
class BossSpider(scrapy.Spider):name = 'boss'# allowed_domains = ['www.xxx.com']start_urls = ['https://www.zhipin.com/job_detail/?query=python%E7%88%AC%E8%99%AB&scity=101010100&industry=&position=']url = 'https://www.zhipin.com/c101010100/?query=python爬虫&page=%d&ka=page-2'page = 1#解析+管道持久化存储def parse(self, response):li_list = response.xpath('//div[@class="job-list"]/ul/li')for li in li_list:job_name = li.xpath('.//div[@class="info-primary"]/h3/a/div/text()').extract_first()salary = li.xpath('.//div[@class="info-primary"]/h3/a/span/text()').extract_first()company = li.xpath('.//div[@class="company-text"]/h3/a/text()').extract_first()#实例化一个item对象item = BossproItem()#将解析到的数据全部封装到item对象中item['job_name'] = job_nameitem['salary'] = salaryitem['company'] = company#将item提交给管道yield itemif self.page <= 3:print('if 执行!!!')self.page += 1new_url = format(self.url%self.page)print(new_url)#手动请求发送yield scrapy.Request(url=new_url,callback=self.parse)

items.py

items.py存放的是我们要爬取数据的字段信息,我们要爬取的是工作名,薪资,公司名。

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.htmlimport scrapyclass BossproItem(scrapy.Item):# define the fields for your item here like:job_name = scrapy.Field()salary = scrapy.Field()company = scrapy.Field()

pipelines.py

pipelines.py主要是对spiders中爬虫返回的数据进行处理的,在这里我们让其写入redis和写入文件,

pipeline可以随意定义,但是它是有顺序的,所以我们要在settings.py设置权重,数字越小,优先级越高。

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.htmlfrom redis import Redis
class BossproPipeline(object):fp = Nonedef open_spider(self, spider):print('开始爬虫......')self.fp = open('./boss.txt','w',encoding='utf-8')def close_spider(self, spider):print('结束爬虫......')self.fp.close()#爬虫文件每向管道提交一次item,则该方法就会被调用一次.#参数:item 就是管道接收到的item类型对象def process_item(self, item, spider):#print(item)self.fp.write(item['job_name']+':'+item['salary']+':'+item['company']+'\n')return item #返回给下一个即将被执行的管道类class redisPileLine(object):conn = Nonedef open_spider(self,spider):self.conn = Redis(host='127.0.0.1',port=6379)print(self.conn)def process_item(self, item, spider):# print(item)dic = {'name':item['job_name'],'salary':item['salary'],'company':item['company']}self.conn.lpush('boss',dic)

settings.py

USER_AGENT="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360EE"
ROBOTSTXT_OBEY=False    #忽略君子协议
ITEM_PIPELINES = {'bossPro.pipelines.BossproPipeline': 300,'bossPro.pipelines.redisPileLine': 301,
}

 

转载于:https://www.cnblogs.com/cuiyuanzhang/p/9493496.html

相关文章:

java 8 lambda reduce_JDK8新特性Lambda表达式体验

“Lambda 表达式”(lambda expression)是一个匿名函数&#xff0c;Lambda表达式基于数学中的λ演算得名&#xff0c;直接对应于其中的lambda抽象(lambda abstraction)&#xff0c;是一个匿名函数&#xff0c;即没有函数名的函数。Java 8的一个大亮点是引入Lambda表达式&#xf…

php display_errors

// 检测开发环境public function setReporting(){if (APP_DEBUG true) {error_reporting(E_ALL);ini_set(display_errors,On);} else {error_reporting(E_ALL);ini_set(display_errors,Off);ini_set(log_errors, On);ini_set(error_log, RUNTIME_PATH. logs/error.log);}} 在p…

linux esd转iso,window_Win10 TH2正式版10586官方ESD映像怎么转换成ISO镜像?,今天phpstudy分享了Win10 TH2(Build - phpStudy...

Win10 TH2正式版10586官方ESD映像怎么转换成ISO镜像?今天phpstudy分享了Win10 TH2(Build 10586)各版本官方ESD映像下载地址&#xff0c;不过旧转换工具可能已不适用于新版ESD映像&#xff0c;特别是新版本增加了专业版和家庭版二合一映像&#xff0c;而以往都是单版本。本文使…

mysql在线上建索引,mysql 5.6在线DDL建索引测试

基本信息&#xff1a;mysql版本&#xff1a;(product)rootlocalhost [(none)]> select version;------------| version |------------| 5.6.29-log |------------1 row in set (0.00 sec)表payment的记录数:(product)rootlocalhost [sakila]> select count(*) from paym…

接口测试(postman jmeter)

接口&#xff1a;把client&#xff08;前端&#xff09;和server&#xff08;后端&#xff09;联系起来的就是接口&#xff0c;接口测试就是功能测试&#xff0c;进行接口测试首先得需要接口文档。 json是一种通用的数据格式&#xff0c;接口返回的数据都是json&#xff0c;jso…

c语言中delay找不到标识符,51单片机的c语言,请问哪里错了?延时没有效果,但是编译又不报错。delay应该怎么写,怎么引用啊?...

最佳答案西岸风2019-01-07 15:15i){LED00;LED21;LED40;delay(5000);}void main(void){while(1){for(i0;i<10;sbit LED0P1^0;sbit LED1P1^1;sbit LED4P1^4;sbit LED5P1^5;sbit LED2P1^2;sbit LED3P1^3;unsigned char i;sbit LED6P1^6;sbit LED7P1^7;void delay(unsigned int …

java 数据类型转换的一场_Java基础 — 四类八种基本数据类型

整型&#xff1a;整数类型int    一般的数据。long    极大的数据。short   用于特定的场合&#xff0c;比如底层的文件处理或者需要控制占用存储单元空间量的大数组。byte   用于特定的场合&#xff0c;比如底层的文件处理或者需要控制占用存储单元空间量的大数组。by…

vs 代理登入

https://msdn.microsoft.com/zh-cn/vstudio/dn771556.aspx转载于:https://www.cnblogs.com/CodingArt/p/6424180.html

php 为啥报错,php Soap 报错 求大神帮忙看看为什么

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼代码&#xff1a;$client new SoapClient("http://116.218.12.10:7012/businessService?wsdl", array(*trace* > true, *exceptions* > true));var_dump($client->__getFunctions());var_dump($client->__…

UWP: ListView 中与滚动有关的两个需求的实现

在 App 的开发过程中&#xff0c;ListView 控件是比较常用的控件之一。掌握它的用法&#xff0c;能帮助我们在一定程度上提高开发效率。本文将会介绍 ListView 的一种用法——获取并设置 ListView 的滚动位置&#xff0c;以及获取滚动位置处的项目。这里多说一句&#xff0c;由…

Deepin ROMS 安装详细流程

按照这个过程&#xff0c;完美安装&#xff0c;当然并不能排除会出现其他的问题。如果遇到了&#xff0c;那就老老实实上网搜吧。 转载于:https://www.cnblogs.com/haoorhuai/p/9502859.html

java struts2值栈ognl_Struts2 (三) — OGNL与值栈

一、OGNL表达式1.概述1.1什么是OGNL​ OGNL是Object-Graph Navigation Language的缩写&#xff0c;俗称对象图导航语言. 它是一种功能强大的表达式语言&#xff0c;通过它简单一致的表达式语法&#xff0c;可以存取对象的任意属性&#xff0c;调用对象的方法&#xff0c;遍历整…

c语言课程设计商品销售系统,c语言课程设计商品销售管理系统.pdf

C语言课程设计商品销售管理系统12020 年 4 月 19 日文档仅供参考商品销售管理系统目录一、 需求分析 2二、概要设计 2三、详细设计 4四、调试分析 14五、用户手册 14六、测试数据 15七、 附录 18— 1—22020 年 4 月 19 日文档仅供参考一、需求分析商品销售管理程序商品信息&am…

uploadhandler.php,WordPress Kernel Theme ‘upload-handler.php’任意文件上传漏洞

javascript中apply、call和bind的区别在JS中,这三者都是用来改变函数的this对象的指向的,他们有什么样的区别呢.在说区别之前还是先总结一下三者的相似之处:1.都是用来改变函数的this对象的指向的.2.第一个参数都是this要指向的对 ...AIX UNIX 系统管理、维护与高可用集群建设—…

selenium--driver.switchTo()

在自动化测试中&#xff0c;会遇到多窗口、多iframe、多alert的情况。此时&#xff0c;会使用driver.switchTo()来解决。 下面时关于driver.switchTo()的详细介绍&#xff1a; 1.多windows操作。 在页面A上操作时&#xff0c;点击某个元素之后&#xff0c;可能会打开新的窗口。…

代理模式-积木模式

代理模式&#xff0d;积木模式 代理模式在实际开发中的确非常常见和常用&#xff0c;表面上代理模式是产生出一个代理类&#xff0c;作为访问实际实现类的代理&#xff0c;控制了外界对实际代理类的访问&#xff0c;在此基础上增加一些增强性的功能。实际上&#xff0c;还将实际…

java调用系统时间函数_JAVA自学笔记:不使用系统函数来计算日期处于当年的第多少天...

前段时间练习了一个求闰年的功能&#xff0c;现在就可以用上啦&#xff0c;这次写一个不借助类库的时间函数&#xff0c;利用基础代码写一个计算求日期处于当年的第多少天的函数。虽然也有简单的方法&#xff0c;例如直接定义每月的天数累加&#xff0c;然后加上当月的天数就可…

c语言输入学生成绩q退出,哭诉、拜求C语言学生成绩管理系统

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼/* Note:Your choice is C IDE */#include "stdio.h"#include "stdlib.h"#include "conio.h"#include "string.h"struct student{int num;char name[20];float score1;float score2;float…

php 所有魔术方法,PHP常用的魔术方法及规则

转&#xff1a;https://www.cnblogs.com/wanglijun/p/10926303.html1. __construct 具有构造函数的类会在每次创建新对象时先调用此方法;初始化工作执行。2. __desstruct 对象的所有引用都被删除或者当对象被显式销毁时执行。3.__call()在对象中调用一个不可访问方法时&#xf…

mysql启动后在哪里编程_启动mysql后怎么连接数据库

推荐答案一.mysql安装百度mysql下载一个即可。只是注意一下几个重要的数据&#xff1a;第一个就是Port Number :3306。端口号默认3306&#xff0c;一般不需要改&#xff0c;如果改了&#xff0c;请记住这个端口号。第二个就是password&#xff1a;本地数据库密码&#xff0c;默…

Python 出现 can't use a string pattern on a bytes-like object

# codingutf-8import urllib.requestimport reurl http://www.163.comfile d:/test.htmldata urllib.request.urlopen(url).read() r1 re.compile(<.*?>)c_t r1.findall(data)print(c_t)发现读取下来后,运行到第9 行,出现: cant use a string pattern on a bytes-l…

2018牛客网暑期ACM多校训练营(第十场)J(二分)

题目描述&#xff1a; 给你n个字符串&#xff0c;要让它们一个一个的合并成一个串。在合并的过程中&#xff0c;要保证被合并的串S是合并后的串r的前缀&#xff0c;模式串t是串r的子序。问你将这n个字符串合并后所得到的字典序最小的串是什么。 题目分析&#xff1a; 首先&…

实用c语言函数源码,C语言编写简单朗读小工具(有源码)

原标题&#xff1a;C语言编写简单朗读小工具(有源码)最近不少人在后台留言说学C都是面对枯燥的控制台程序&#xff0c;能不能体现一下C语言的实际用途&#xff0c;今天我们就理论结合实践一把&#xff1a;C语言结合VBS脚本编写一个简单的朗读小工具&#xff0c;做一个能够发音的…

php监听订单状态,ecshop数据库订单状态判断

order_info 表刚下完订单order_status 0shipping_status 0pay_status 0取消order_status 2shipping_status 0pay_status 0确认order_status 1shipping_status 0pay_status 0已付款order_status 1shipping_status 0pay_status 2配货中order_status 1shipping_status 3pay_status…

flask异步操作_Python Flask后端异步处理(三)

前一篇博文我们已经将基础知识和环境配置进行了介绍&#xff1a;首先编写一个celerytask.py文件进行Celery的配置&#xff0c;同时耗时任务也写在该文件中from celery import Celeryfrom init import appfrom SZheConsole import SZheScanapp.config[CELERY_BROKER_URL] redis…

Codeforces Round #308 (Div. 2) C. Vanya and Scales dfs

题目链接: http://codeforces.com/contest/552/problem/C 题意: 给你100个砝码&#xff0c;第i个砝码质量是w^i&#xff0c;然后问你能不能在有m的情况下&#xff0c;左边和右边都放砝码&#xff0c;使得这个天平平衡 题解: dfs直接暴力 对于这个砝码来说&#xff0c;只有3种选…

java中JVM的原理【转】

一、java虚拟机的生命周期&#xff1a; Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务&#xff1a;执行Java程序。程序开始执行时他才运行&#xff0c;程序结束时他就停止。你在同一台机器上运行三个程序&#xff0c;就会有三个运行中的Java虚拟机。 Java虚拟…

switch的case使用数组C语言,使用常量数组的元素作为switch语句中的case

我正在尝试将一组按键映射到一组命令.因为我处理来自多个地方的命令,所以我想在键和命令之间设置一个抽象层,这样如果我更改底层键映射,我就不必更改很多代码.我目前的尝试看起来像这样:// input.henum LOGICAL_KEYS {DO_SOMETHING_KEY,DO_SOMETHING_ELSE_KEY,...countof_LOGIC…

PHP上传文件函数move_upload,如何使用php中move_uploaded_file函数

我们平时上传的文件保存在临时文件夹中&#xff0c;例如/ tmp&#xff0c;但临时文件夹的内容在一段时间后会被删除&#xff0c;因此为了将来要使用上传文件&#xff0c;需要将内容保存在不太可能被任意删除的专用目录中&#xff0c;这时就需要使用move_uploaded_file函数&…

java的标记接口_Java中的标记接口?

我被教授&#xff0c;Java中的Marker接口是一个空接口&#xff0c;用于向编译器或JVM发送信号&#xff0c;实现此接口的类的对象必须以特殊方式处理&#xff0c;如序列化&#xff0c;克隆等。但最近我了解到&#xff0c;它实际上与编译器或JVM无关。例如&#xff0c;在Serializ…