scrapy基础
- 基本的案例:
- JsonItemExporter和JsonLinesItemExporter:(items类型简单存json)
- settings 的基本设置
- 自动填写完整网页
- scrapy的工程建立
- pipelines 的使用
- 翻页实现请求(scrapy.Request)
- item的使用
- scrapy 中的类: CrawlSpider
- 不在命令行执行(在pycharm执行)
- 登录请求的时候:(需要重写start_requests 函数才可以)
- 需要验证码的一些操作!
- 用pipelines 的自带方法 存储文件
- middlewares.py 的一些注意事项:
- 使用middlewares.py 设置不同的请求头
- 在middlewares 使用selenium 动态网页的爬取
- 使用代理的方法:
- 通过异步 存储pymysql
- 反反爬虫机制
- 一些警告 :
基本的案例:
1.建立scrapy 的工程后和爬虫py文件后:
①spiders 的文件夹里面是建立的爬虫py文件,是我们需要写的文件
②自己建立的文件(lsbk) 这文件实现相应自己想实现的东西(获取到数据)
import scrapy
# 这个很重要调用了 items 里面的一个类
from ..items import AllspiderItem
class LsbkSpider(scrapy.Spider):
name = 'lsbk'
allowed_domains = ['www.qiushibaike.com/text/']
start_urls = ['https://www.qiushibaike.com/text/'] # 建立好爬虫后最好改一下网址
def parse(self, response):
# 接下来获取一个名字
div_list=response.xpath('//div[@class="col1 old-style-col1"]/div')
for div in div_list:
name=div.xpath('.//div[@class="author clearfix"]//h2/text()').get()
# 这个将 name 转化成AllspiderItem类型
yield AllspiderItem(name=nam
# 这里yield 之后还可以写代码哦!(翻页什么的都还可以去试一下!)
③itmes.py 里面的文件是 让我们可以定义一个类型变量
import scrapy
class AllspiderItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 这里就就把name 设置成AllspiderItem的这种类型
name=scrapy.Field()
④pipelines.py 是用来存文件的是来接收自己写的爬虫(lsbk) yield 过来的信息
# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import json
class AllspiderPipeline:
# 定义初始
def __init__(self):
self.fp=open("name.json","w",encoding="utf-8")
# 每次进入pipelines.py 都会首先调用这个open_spider函数(注意参数有两个)
def open_spider(self,spider):
print("爬虫开始了......")
# 这个函数是之前就定义好了的 实现存储
def process_item(self, item, spider):
# items 是 (lsbk) yield 过来的信息
json_name=json.dumps(dict(item),ensure_ascii=False)
print(json_name)
self.fp.write(json_name+"\n")
return item
# 进入这个文件后,最后以这个执行close_spider函数结束:
def close_spider(self,spider):
self.fp.close()
print("爬虫结束了!")
说到使用这个items 后就应该 简单方法存json
JsonItemExporter和JsonLinesItemExporter:(items类型简单存json)
保存json数据的时候,可以使用这两个类,让操作变得得更简单。
1.JsonItemExporter:这个是每次把数据添加到内存中。最后统一写入到磁盘中。好处是,存储的数据是一个满足json规则的数据。坏处是如果数据量比较大,那么比较耗内存。
代码:
from scrapy.exporters import JsonItemExporter
class AllspiderPipeline:
# 定义初始
def __init__(self):
# 这里打开文件很重要 必须是bite类型不能有encoding了,开了要关
self.fp=open("name.json","wb")
self.exporter=JsonItemExporter(self.fp,ensure_ascii=False)
def open_spider(self,spider):
print("爬虫开始了......")
def process_item(self, item, spider):
self.exporter.export_item(item)
return item
def close_spider(self,spider):
# 要记得关闭
self.exporter.finish_exporting()
self.fp.close()
print("爬虫结束了!")
2.JsonLinesItemExporter:这个是每次调用export_item
的时候就把这个item存储到硬盘中。坏处是每一个字典是一行,整个文件不是一个满足json格式的文件。好处是每次处理数据的时候就直接存储到了硬盘中,这样不会耗内存,数据也比较安全。
from scrapy.exporters import JsonLinesItemExporter
class AllspiderPipeline:
# 定义初始
def __init__(self):
# 这里打开文件很重要 必须是bite类型不能有encoding了,可以不关了
self.fp=open("name.json","wb")
self.exporter=JsonLinesItemExporter(self.fp,ensure_ascii=False)
def open_spider(self,spider):
print("爬虫开始了......")
def process_item(self, item, spider):
self.exporter.export_item(item)
return item
def close_spider(self,spider):
self.fp.close()
print("爬虫结束了!")
⑤ 记得设置 settings.py 里的ITEM_POPELINES 记得取消注释
ITEM_PIPELINES = {
'allspider.pipelines.AllspiderPipeline': 300,
}
settings 的基本设置
这个一般都要打开,不是有些爬不了
ROBOTSTXT_OBEY = False
请求头:
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36'
关闭那些繁琐的提醒:(填在user_agent上面就行)
LOG_LEVEL="WARNING"
这个是等三秒在爬下一个网页
DOWNLOAD_DELAY = 3
自动填写完整网页
import urllib
# 自动填写完整网页:
urllib.parse.urljoin()
在scarpy 里面 用 response.urljoin() 也可以填写完整的网页!
scrapy的工程建立
win10 cmd
相应命令行:
cd c:/jj 到c盘jj文件
清除cmd的所有文字
cls
1.创建一个scarpy的项目: scarpy startproject name —name 是工程名字
2.生成一个爬虫
在文件里面有sprider文件建立一个爬虫
scarpy genspider name “xxxxx” -----name 是文件名字, xxx是限制
3.完善爬虫
4.运行爬虫
在建立工程的项目里面 运行scrapy crawl name —name 是建立的爬虫名字
pipelines 的使用
翻页实现请求(scrapy.Request)
需要在建立的spider文件创建一个request对象,用yield 反回给self.parse
scrapy.Requests知识点:
Request对象在我们写爬虫,爬取一页的数据需要重新发送一个请求的时候调用。这个类需要传递一些参数,其中比较常用的参数有;
1. url:这个request对象发送请求的url。
2. callback :在下载器下戟完相应的数据后执行的回调函数。
3. method:请求的方法。默认为GET方法,可以设置为其他方法。
4. headers : 请求头,对于一些固定的设置,放在 settings.py 中指定就可以了。对于那些非固定的,可以在发送请求的时候指定。
5. meta :比较常用。用于在不同的请求之间传递数据用的。
6. encoding :编码。默认的为utf-8 ,使用默认的就可以了。
7. dot_filter:表示不由调度器过滤。在执行多次重复的请求的时候用得比较多。
8. errback :在发生错误的时候执行的函数。
meta 是很重要的是用来传数据的,
item :是在item.py 建立的的一个存储数据的对象
yield scrapy.Request(
url=" " # 这个是下一个要去的url 地址
callback=self.fangfa #这个是传入哪个方法进行实现
meta={"item":item} # 把之前item 的数据也传送过去
)
def fangfa(self,response): # 这里是自己定义的一个方法(这里记得有response的对象)
item=response.meta["item"] # 在这里接收之前的item 的数据
...
..
然后传过来了response对象之后,response 能干嘛呢?
Response对象:
Response对象一般是由 scrapy 给你自动均建的。因此开发者不需要关心如何创建Response对象,而是如何使用他。Response对象有很多属性,可以用来提取数据的。
主要有以下属性:
1. meta:从其他请求传过来的meta属性,可以用来保持多个请求之间的数据连接
2. encoding:返回当前字符串编码和解码的格式。
3. text:将返回来的数据作为 unicode字符串返回。
4. body:将返回来的数据作为 bytes字符串返回。
5. xpath: xapth选择器。
6. css: css选择器。
一个实例:
import scrapy
class HrSpider(scrapy.Spider):
name = 'hr'
allowed_domains = ['tencent.com']
start_urls = ['http://www.cqie.edu.cn/html/3/jsfc/jsfc/']
def parse(self, response):
li_list=response.xpath('//div[@class="sortlist"]//ul/li')
for li in li_list:
a={}
a['data']=li.xpath('.//a/text()').extract_first()
yield a #返回数据pipelines 里面去
next_url=response.xpath('//div[@class="page"]/a[last()-1]/@href').extract_first() #获取下一个url 地址
next_name=response.xpath('//div[@class="page"]/a[last()-1]/text()').extract_first()
if(next_url!=[] and next_name=="下一页"):
next_url="http://www.cqie.edu.cn/html/3/jsfc/jsfc/"+next_url
#返回request对象
yield scrapy.Request(
url=next_url,
callback=self.parse, # 这里自己调用自己
dont_filter=True
)
item的使用
item 是用来定义类型,是用来分辨,是哪个爬虫的获取的数据,而且也可以定义数据,以防出错
使用:在建立了之后在建立的爬虫需要 调用item 这个包
在爬虫py文件调用 from myspider.items import myItem
在爬虫文件也使用myItem 类型来装数据
a=myItem() #使用对象定义的数据
a['name']=li.xpath('.//a/text()').extract_first()#赋值
class myItem(scrapy.Item):-->scrapy.Item 也是一个字典
# define the fields for your item here like:
name = scrapy.Field()--->scrapy.Field() 是一个字典
pass
我们把定义的myItem理解为一个字典
1.在获取数据的时候,使用不同的item来存放不同的数据
2.建立多个item类型存多个爬虫不同的数据
3.在交给pipeline的时候,可以通过isinstance(item,myItem)来判断是属于哪个item,进行不同数据的(item)处理
scrapy 中的类: CrawlSpider
- 步骤:
- 建立一个爬虫 跟之前的 一般的scrapy很像 就一个点不一样
- scrapy genspider -t crawl 爬虫名 url 地址
- 指定 star_url(起始地址) ,对应的响应会经过reles 提取url地址
- 完事 relues ,添加Rule
不在命令行执行(在pycharm执行)
建立一个.py 文件来执行 命令行(我这里建立的是start)
# 调用库
from scrapy import cmdline
# 这个是执行命令的, 这些命令必须要是 列表, 转化: "scrapy crawl ftt" ==> ['scrapy', 'crawl', 'ftt']
cmdline.execute("scrapy crawl ftt".split())
登录请求的时候:(需要重写start_requests 函数才可以)
- 需要重新start_requests 函数
- 记得用scrapy.FormRequest post方法传递!
import scrapy
class WeSpider(scrapy.Spider):
name = 'we'
allowed_domains = ['https://www.csdn.net/']
start_urls = ['https://passport.csdn.net/login?code=public']
def start_requests(self):
post_data=dict(
username='',账号
password="",密码
loginType="1",
pwdOrVerifyCode="sadasdasd",
uaToken="14,#USFrDfP6zzF79zo22ZKFCtSd03sNdNDQeNT59uNxzWa+vT6jt5yogp9TDkA7FJJ81u3Bpslg5VOLqAFmqMyxruWqlbzxgPQQreRCzznOv2NVltQzzPzbVXlqlbrDgbqgRNJaxzFi2Duvlp1xoFr0VmCqSQdb2fc+epYDzFQiQ28HzMKPEY9LMZ2aMXKkXSmWv19EiRpt6Zi0FZw9K4Wu+vnXFRsFxYw3tnkxlBmOacUvNyxntavMEgA/t5RwLY2ByHwd7sp4X2w4aBGaDrq6l8YlySFX61UjvBhr7AsmUtUmPeo4m2Rxme/80rowmICn8hjpOCYNIgQEaqKxCfPOIjGOrFwYfLgfzjo9Zhb10BLDpnwNtVCGpsOf6FMiMuPvkcTwcJ4pVV+wRnkFKC+e6FWPsKD19d4h7FiSMCZHvbqZnwCoOUhMC6xxSNMQKbOzql7L8NIoWORdreqko5F60L9A42YeYzWQGDGdeALXlGDe8FyBzK1I9Xv8waDqU4LxUqzItIkGjQSe+f6ZXBVYfoJPGOGCTcrS68NZZmJwSZw80YA0Oml0hcDh32w64O70BIPF0iZjgsSzydELb0olySYylSvvUwvXJS0103M79EWxiQWXxGsMFD9BpnYjipyLdsfaAmYuA4U/LpdekCq/q96KQalrODJkEL4bRyhNChSgMIMeFT8IXwXYzAVwPsG8cATHIw/IU8GeXR5TRgyFcUxD3Tdz8FUOD6dCfvWbTrJaeDFjU6EZFwPUUrI0W6WzWvSSBG9y+nCRg0bDCyAuZOTt5NhpyqkU/P6QOb5CUdXtHHhRX7sbzlfv7qcgNOwl3kh5/9r9Mtp/zmKaqX+ks6LPiclcf28GIur/QP9PH5vNrrtfu8Q1qah9z++yD7gwLHKaHgiUdP2Pz+bYdY0fOc7OJS/vUdJCoP04JhVOqQb5bg5y5VP7wHWuVkkX1WPdnfzk64E7od+eS60mhLecEk/tlslrV8JAhSbeDUXiU8GG9nvZqfnPdTKNsoT/1zjWRW9SA9/W82jjYQzVY7To/Ls6qtZ4ZkqtVlxcVeiH/i9lf8opyAg/uQFjA0Wtb3W+plHEjq5QvZ4B4SCmHZWmc4r4wzleG7sfh92KTwtp6lNh3coEyqldpfa/p3akDetauOk7nK4A9ARuKR1aR/Crg1O7JI7KPH+792CRuSvrCMMDmCptLmUWZ6Z+WooyePcLsvyfuSHjdD+khkKh402FYZJh5iR7JqSNhAifTom9Gs1cdT31loIcB3DJ7jP2Hu9cbpXw3+m+W3oGwWUQ1TBwuVISu2yEO+9j9HkQ+NPB0uub/NcEpCXJ+g9iyEPQT1veJfvOEMJ/+ViStaBoty3VKKNXz398gPnfmxZ1J04LZUMcyG0ecK7uo4u=",
userIdentification="1191529983@qq.com",
webUmidToken="T2gAnAV9vl3KcXJtpzJ-8_GlAbnUVUBvN1ylGrQhA7YgCPJYjWIEzp7lGBLrWufp9cY=",
)
# 这个地方需要用 Formrequest
yield scrapy.FormRequest(
"https://passport.csdn.net/v1/register/pc/login/doLogin",
formdata=post_data,
callback=self.pase1
)
def pase1(self,response):
print("你好!")
print(response.text)
需要验证码的一些操作!
利用 PIL 模块
获取 验证码的图片存在本地,然后打开图片!然后自己输入 验证码 在发送post 请求!
import requests
from PIL import Image
from lxml import etree
url="http://passport2.chaoxing.com/login?"
headers={"user-agent": 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'}
r=requests.get(url,headers=headers)
r.encoding="utf-8"
content=etree.HTML(r.text)
img_url=content.xpath('//img[@id="numVerCode"]/@src')
img_file=requests.get(img_url,headers)
with open("1.jpg","wb") as f: # 存验证码的照片!
f.write(img_file.content)
image=Image.open("1.jpg")
image.show() # 把图片展示出来!
numcode=input("请输入验证码!")
data={
'refer_0x001': 'http%3A%2F%2Fi.mooc.chaoxing.com',
'pid': '-1',
'fid': -1,
'allowJoin': 0,
'isCheckNumCode': 1,
'f': 0,
't': 'true',
'uname': 18323416055,
'password': 'aGVpaGVpMTIzMC4=',
# 'numcode': 4141, --------------这个是 你看见的验证码
}
data[numcode]=numcode # 把验证码输入进去!
# 在请求需要登录的页面!
r=requests.post(url,headers=headers,data=data)
print(r.text)
用pipelines 的自带方法 存储文件
因为:觉得有点麻烦所以吧所有代码搬来了!
这个是图片的保存
1.首先是第一个 建立的 pipe.py 文件:
图片url 传参 必须用 imge_urls (必须用这个参数)
import scrapy
# from allspider.items import AllspiderItem
from ..items import AllspiderItem # 这里需要 调用 item.py 这个文件
class PipeSpider(scrapy.Spider):
name = 'pipe'
allowed_domains = ['www.ituring.com.cn']
start_urls = ['https://www.ituring.com.cn/book']
def parse(self, response):
li_list=response.xpath('//div[@class="block-books block-books-grid"]/ul/li')
for li in li_list:
name=li.xpath('.//div[@class="book-img"]/a/@title').get()
image_urls=li.xpath('.//div[@class="book-img"]/a/img/@src').getall()
'这里要下载的图片url 传参 必须用 imge_urls (必须用这个参数),因为要用别人写的函数 这个传入参数是一个 列表[ ]'
item=AllspiderItem(name=name,image_urls=image_urls)
yield item
2.item.py 文件
import scrapy
class AllspiderItem(scrapy.Item):
# define the fields for your item here like:
name = scrapy.Field()
image_urls=scrapy.Field() # 这个文件与之前的 pipe.py 相呼应
images=scrapy.Field() # 要使用这个 images 因为它会检测是否有这images,并执行!
3.setting 文件:
这个是需要修改的它原函数,满足自己需求的设置
这下面的要打开设置相关的值:
LOG_LEVEL="WARNING" # 这个是去掉一些无用的信息
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36' # 设置一个反反爬虫头
ROBOTSTXT_OBEY = False # 这个不遵守 root 协议 懂得都懂
ITEM_PIPELINES = { 'allspider.pipelines.AllspiderPipeline' : 1 } 这个是关键 这个要用你自己写的pipelines 的函数
如果没有想改变的:
LOG_LEVEL="WARNING" # 这个是去掉一些无用的信息
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36' # 设置一个反反爬虫头
ROBOTSTXT_OBEY = False # 这个不遵守 root 协议 懂得都懂
ITEM_PIPELINES = { 'scrapy.pipelines.images.ImagesPipeline' : 1 } 这个是关键 这个要用你自己写的pipelines 的函数
IMAGES_STORE=r"./im" 图片要存的路径,这个要设置
4.pipelines.py
这个是自己想要重新 修改存储的项目
from itemadapter import ItemAdapter
import os
from scrapy.pipelines.images import ImagesPipeline
这个重新写的pipelines继承与ImagesPipeline,改相关数据
class AllspiderPipeline(ImagesPipeline):
重写这个 get_media_requests 这个方法:
def get_media_requests(self, item, info):
把这个请求网页的父类对象 得到,把item传进去
request_objs=super(AllspiderPipeline,self).get_media_requests(item,info)
for request_obj in request_objs:
request_obj.item=item
# 返回对象
return request_objs
def file_path(self, request, response=None, info=None, *, item=None):
继承之前的路径 其实也可以不要这个,可以自己写
path=super(AllspiderPipeline,self).file_path(request,response,info)
'''获取之前写的名字'''
name=request.item.get('name')
'''设置自己想要的路径'''
img_star=r"./im"
name_path=os.path.join(img_star,name)
img_path=os.path.join(name_path,name+".png")
print(img_path)
# 返回路径
return img_path
== 如果不想自己设计==
这个pipelines.py 不用写 因为调用不到这个pipelines
middlewares.py 的一些注意事项:
在middlewars里面的一个类,在settings 里面开启了的:
类里面的一个方法:process_request(self,request,spider)
这个方法如果返回的是一个response对象 它会直接返回自己的爬虫
如果返回的是一个request对象
使用middlewares.py 设置不同的请求头
uesagent.py 这个直接创建的爬虫只是简单的获取这个头
import scrapy
import json
class UseagentSpider(scrapy.Spider):
name = 'useagent'
allowed_domains = ['http://httpbin.org/']
start_urls = ['http://httpbin.org/user-agent']
def parse(self, response):
head=json.loads(response.text)["user-agent"]
print(head)
middlewares.py
这里面需要添加自己写的类:
重新process_request 方法 随机获取 请求头
设置请求头
import random
class tang(object):
u_list=[
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'
]
def process_request(self,request,spider):
ues=random.choice(self.u_list)
request.headers["User-Agent"]=ues
setting.py
需要打开的文件:
LOG_LEVEL="WARNING"
ROBOTSTXT_OBEY = False
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'USER_AGENT ':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'
}
----------这一步最关键-----------这个是用了我们之前在middlewares.py 写的 tang 类
DOWNLOADER_MIDDLEWARES = {
都要注意 都要以 自己的文件名字 设置相应的设置不能直接搬去
'use_agent.middlewares.tang': 543,
}
在middlewares 使用selenium 动态网页的爬取
原理是: middlewares 里面改变 process_request 函数,
因为process_request 如果返回值是一个response对象,它就会返回到自己写的爬虫里面,所以我们在这里自己请求完整网页的源代码,然后在返回到自己写的爬虫里面
from selenium import webdriver
import time
from scrapy.http.response.html import HtmlResponse
# 这里重新定义了一个类
class MacBookmiddlewares:
def __init__(self):
path = r"C:\Program Files\Google\Chrome\Application\chromedriver.exe"
self.driver = webdriver.Chrome(executable_path=path)
# 用 selenium 的特性 把 网页完整的代码获取下来
def process_request(self,request,spider):
self.driver.get(request.url)
time.sleep(1)
try:
while True:
self.driver.find_element_by_id("show_more").click()
time.sleep(0.5)
if not None:
break
except:
pass
source=self.driver.page_source
# 这里注意一下参数,应该怎么填写 response=HtmlResponse(url=self.driver.current_url,body=source,request=request)
return response
使用代理的方法:
使用代理和之前 使用不一样的请求头是几乎差不多
就需要设置 setting 和 middlewares.py
第一开发代理 :
1.设置 middlewares.py
一样是自己写一个类:
class agency(object):
agency_list=[] # 这里填写一些代理地址
def process_request(self,request,spider):
agen=random.choice(self.agency_list)
request.meta['proxy']=agen
2.setting 设置:
LOG_LEVEL="WARNING"
ROBOTSTXT_OBEY = False
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'USER_AGENT ':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'
}
----------这一步最关键-----------这个是用了我们之前在middlewares.py 写的 agency 类
DOWNLOADER_MIDDLEWARES = {
都要注意 都要以 自己的文件名字 设置相应的设置不能直接搬去
'use_agent.middlewares.tang': 543, 这个是上次请求头
'use_agent.middlewares.agency': 100, 这个是申请的代理
}
第二个: 独享代理
class agency(object):
def process_request(self,request,spider):
proxy='这里写端口号!'
user_password ="这里写密码!"
request.meat['proxy']=proxy
bytes 类型 base64.b64encode("这里必须是bytes类型") 用 encode("utf-8") 就OK了
b64_user_passsword=base64.b64encode(user_password.encode('utf-8'))
request.headers['proxy-Authorization']="Basic"+b64_user_passsword.decode('utf-8')
通过异步 存储pymysql
这里是在pipelines.py 里面写的类
from twisted.enterprise import adbapi
from pymysql import cursors
class ASYNCHpipeline(object):
def __init__(self):
data={
'host':'你的数据库地址',
'user' :'用户名',
'password':'密码',
'database':'数据库名',
'charset':'utf8',
# 这里传入游标的类
'cursorclass':cursors.DictCursor
'port':3306
}
# 传入相关的 参数!
self.dbpool=adbapi.ConnectionPool('pymysql',**data)
self._sql=None
@property
def sql(self):
if not self._sql:
# 这里写sql 语句
self._sql='''
insert into test(num) value(%s)
'''
return self._sql
return self._sql
def process_item(self,item,spider):
# 这里就通过runInteraction函数 实现 异步
defer=self.dbpool.runInteraction(self.insert_item,item)
# 这里是写 如果那里出错了 就调用 出错函数!
defer.addErrboack(self.handle_error,spider)
# 这里写 异步函数
def insert_item(self,cursor,item):
cursor.execute(self._sql,1)
def handle_error(self,error,item,spider):
print(error)
== 需要在setting== 里面设置打开使用这个类:
DOWNLOADER_MIDDLEWARES = {
都要注意 都要以 自己的文件名字 设置相应的设置不能直接搬去
'use_agent.middlewares.ASYNCHpipeline': 100, # 这个是开启异步处理的类!
}
反反爬虫机制
"这里设置请求数太快会被识别到"
# Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS = 1
修改下载延迟时间,DOWNLOAD_DELAY设置越大请求越慢
DOWNLOAD_DELAY = 3
#默认False;为True表示启用AUTOTHROTTLE扩展
AUTOTHROTTLE_ENABLED = True
#默认5秒;初始下载延迟时间
AUTOTHROTTLE_START_DELAY = 1
#默认60秒;在高延迟情况下最大的下载延迟
AUTOTHROTTLE_MAX_DELAY = 3
一些警告 :
parse 函数运行次数多了?
- yield scrapy.FormRequest 如果没有设置 callback 他会默认传到parse 函数里面去