爬虫学习笔记

Python3 爬虫教程


学习网站:https://www.bilibili.com/video/av9784617?from=search&seid=3311514956616305524

BeautifulSoup

是用来解析HTML元素、形成标签树的库。

在HTML中,每个元素tag包含:标签名tag.name、属性域tag.attris、内容字符串tag.string。

HTML文档–>标签树–>BeautifulSoup类

​ BeautifulSoup 类的基本元素

基本元素说明
Tag标签,最基本的信息组织单元,分别用<>和</>标明开头和结尾
Name标签的名字,

的名字’p’,格式:.name
Attributes标签的属性,字典形式组织,格式:.attrs
NavigableString标签内非属性字符串,<>…</>中字符串,格式:.string
Comment标签内的字符串的注释部分,一种特殊的Comment类型
import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
soup=BeautifulSoup(r.text,"lxml")
print(soup.a) #打印第一个a标签内容  
print(soup.a.name) #打印a标签的名字
print(soup.a.parent.name)#打印a父亲标签的名字
print(soup.a.attrs)#打印a标签中的属性
print(soup.a.attrs["class"])#打印a标签中class属性的值
print(type(soup.a.attrs))#打印标签属性通过处理后的类型
print(type(soup.a))#标签的类型
print(soup.a.string)#打印标签内字符串信息

http://python123.io/ws/demo.html内容:

<html>
	<head>
		<title>This is a python demo page</title>
	</head>
	<body>
		<p class="title">
			<b>The demo python introduces several python courses.</b>
		</p>
		<p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:
			<a href="http://www.icourse163.org/course/BIT-268001" class="py1" id="link1">Basic Python</a> 
			and 
			<a href="http://www.icourse163.org/course/BIT-1001870001" class="py2" id="link2">Advanced Python</a>.
		</p>
	</body>
</html>
HTML标签的基本树形结构

image-20191205005631201.png

​ 标签树的下行遍历

属性说明
.contents子节点的列表,将所有儿子节点存入列表
.children子节点的迭代类型,与.contents类似,用于循环遍历儿子节点
.descendants子孙节点的迭代类型,包含所有子孙节点,用于遍历循环
import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
soup=BeautifulSoup(r.text,"lxml")
print(soup.head.contents)#返回head标签子节点的列表
print(soup.body.contents)#返回body标签子节点的列表
print(len(soup.body.contents))#返回列表长度
print(soup.body.contents[1])#返回列表中的第二个元素


for child in soup.body.children:#遍历儿子节点
    print(child)
    
for desc in soup.body.descendants:#遍历孙子节点
    print(desc)

​ 标签树的上行遍历

属性说明
.parent节点的父亲标签
.parents节点先辈标签的迭代类型,用于循环遍历先辈节点
import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
soup=BeautifulSoup(r.text,"lxml")

print(soup.title.parent)#打印title的父标签
print(soup.html.parent)#打印html的父标签

for parent in soup.a.parents:#遍历a标签的所有父标签
    if parent is None:
        print(parent)
    else:
        print(parent.name)

​ 标签树的平行遍历

属性说明
.next_sibling返回按照HTML文本顺序的下一个平行节点标签
.previous_sibling返回按照HTML文本顺序的上一个平行节点标签
.next_siblings迭代类型,返回按照HTML文本顺序的后续所有平行节点标签
.previous_siblings迭代类型,返回按照HTML文本顺序的前续所有平行节点标签

平行遍历发生在同一个父节点下的各节点间

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
soup=BeautifulSoup(r.text,"lxml")

print(soup.a.next_sibling)#返回a标签下一个平行节点标签
print(soup.a.next_sibling.next_sibling)#返回a标签下下一个平行节点标签
print(soup.a.previous_sibling)#返回a标签前一个平行节点标签

for sibling in soup.a.next_siblings:#平行遍历后续节点
    print(sibling)
    
for sibling in soup.a.previous_siblings:#平行遍历前续节点
    print(sibling)

基于bs4库的HTML格式和编码

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
soup=BeautifulSoup(r.text,"lxml")

print(soup.prettify())#格式化输出

输出:

image-20191205015937483.png

三种信息标记

image-20191205020637188.png
image-20191205020718385.png
在这里插入图片描述

image-20191205020836078.png

基于bs4库的HTML内容查找方法

<>.find_all(name,attrs,recursive,string,**kwargs)

返回一个列表类型,存储查找结果

name:对标签名称的检索字符串

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
soup=BeautifulSoup(r.text,"lxml")

print(soup.find_all("a"))#返回所有a标签

print(soup.find_all(["a","b"]))#返回所有a标签和b标签

attrs:对标签属性值的检索字符串,可标注属性检索

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
soup=BeautifulSoup(r.text,"lxml")

print(soup.find_all("p","course"))#返回p标签属性值为'course'的标签

print(soup.find_all(id='link1'))#查找属性id='link1'的标签

recursive:是否对子孙全部检索,默认为True

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
soup=BeautifulSoup(r.text,"lxml")

print(soup.find_all('a', recursive=False) #该文档的第一层子标签没有a标签)

string:<>…</>中字符串区域的检索字符串

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
soup=BeautifulSoup(r.text,"lxml")

print(soup.find_all(string="Basic Python"))#精确查找相关字符串

扩展方法:

方法说明
<>.find()检索且只返回一个结果,字符串类型,同.find_all()参数
<>.find_parents()在先辈节点中搜索,返回列表类型,同.find_all()参数
<>.find_parent()在先辈节点中返回一个结果,字符串类型,同.find()参数
<>.find_next_siblings()在后续平行节点中搜索,返回列表类型,同.find_all()参数
<>.find_next_sibling()在后续平行节点中中返回一个结果,字符串类型,同.find()参数
<>.find_previous_siblings()在前续平行节点中搜索,返回列表类型,同.find_all()参数
<>.find_previous_sibling()在前续平行节点中中返回一个结果,字符串类型,同.find()参数
中国大学排名实例
from bs4 import BeautifulSoup
import requests
import bs4

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        # r.encoding=r.apparent_encoding
        r.encoding = 'utf-8'
        return r.text
    except:
        print("获得网站文本失败!")

def fillUniList(html, num, uInfo):
    count = 1
    s = BeautifulSoup(html, 'html.parser')
    for tr in s.find('tbody').children:
        if isinstance(tr, bs4.element.Tag):
            tds = tr('td')
            uInfo.append([tds[0].string, tds[1].string, tds[3].string])
            count += 1
        if count>num: 
            break

def printUniList(uInfo): 
    tplt = "{0:^10}\t{1:^10}\t{2:^10}"
    print(tplt.format("排名", "学校", "总分"))
    for i in range(len(uInfo)):
        u = uInfo[i]
        print(tplt.format(u[0], u[1], u[2]))

def main():
    url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html'
    num = 20
    uInfo = []
    html = getHTMLText(url)
    fillUniList(html, num, uInfo)
    printUniList(uInfo)

if __name__ == '__main__':
	main()

正则表达式

操作符说明实例
.表示任何单个字符
[]字符集,对单个字符给出取值范围[abc]表示a或b或c;[a-z]表示a到z单个字符
[^ ]非字符集,对单个字符给出排除范围[^abc]表示非a或b或c的单个字符
*前一个字符0次或无线次扩展abc*表示ab或abc或abcc等
+前一个字符1次或无线次扩展abc+表示abc或abcc等
?前一个字符0次或1次扩展abc?表示ab或abc
|左右表达式任意一个abc|def 表示abd或def
{m}扩展前一个字符m次ab{2}c表示abbc
{m,n}扩展前一个字符m到n次(含n)ab{1,2}c表示abc或abbc
^匹配字符串开头^abc表示abc且在一个字符串的开头
$匹配字符串结尾abc$表示abc且在一个字符串的结尾
()分组标记,内部只能使用|操作符(abc)表示abc,(abc,def)表示abc或def
\d数字,等价于[0-9]
\w单词字符,等价于[A-Za-z0-9]

1+$ : 由26个字母组成的字符串

^-?\d+$ : 整数形式的字符串

2+[0-9]*$:正整数形式的字符串

Re库

​ Re库主要功能函数

函数说明
re.search()在一个字符串中搜索匹配正则表达式的附一个位置,返回match()对象
re.match()从一个字符串的开始位置起匹配正则表达式,返回match对象
re.findall()搜索字符串,以列表类型返回全部能匹配的子串
re.split()将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
re.finditer()搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象
re.sub()在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串

​ flags可选择值

常用标记说明
re.I re.IGNORECASE忽略正则表达式的大小写,[A-Z]能匹配小写字符
re.M re.MULTILING正则表达式中的^操作符能够将给定字符串的每行当做匹配开始
re.S re.DOTALL正则表达式中的 . 操作符能够匹配所有字符,默认匹配除换行符外的所有字符
re.search()

re.search(pattern,string,flags=0)

在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象

  • pattern:正则表达式的字符串或原生字符串表示
  • string:待匹配字符串
  • flags:正则表达式使用时的控制标记
import re
match=re.search(r'[1-9]\d{5}','BIT 100081')
if match:
    print(match.group(0))
re.match()

re.match(pattern,string,flags=0)

从一个字符串的开始位置起匹配正则表达式,返回match对象

  • pattern:正则表达式的字符串或原生字符串表示
  • string:待匹配字符串
  • flags:正则表达式使用时的控制标记
import re
match=re.match(r'[1-9]\d{5}','100081 BIT')
if match:
    print(match.group(0))
re.findall()

re.findall(pattern,string,flags=0)

搜索字符串,以列表类型返回全部能匹配的子串

  • pattern:正则表达式的字符串或原生字符串表示
  • string:待匹配字符串
  • flags:正则表达式使用时的控制标记
import re
f_all= re.findall(r"[1-9]\d{5}","BT100081 SH132132 FJ132431432")
print(f_all)
re.split()

re.split(pattern,string,maxsplit=0,flags=0)

将一个字符串按照正则表达式匹配结果进行分割,返回列表类型

  • pattern:正则表达式的字符串或原生字符串表示
  • string:待匹配字符串
  • maxsplit:最大分割数,剩余部分作为最后一个元素输出
  • flags:正则表达式使用时的控制标记
import re
print(re.split(r'[1-9]\d{5}','dad100081 fsv100084'))
print(re.split(r'[1-9]\d{5}','dad100081 fsv100084',maxsplit=1))
re.finditer()

re.finditer(pattern,string,flags=0)

搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象

  • pattern:正则表达式的字符串或原生字符串表示
  • string:待匹配字符串
  • flags:正则表达式使用时的控制标记
import re
for i in re.finditer(r'[1-9]\d{5}','dad100081 fsv100084'):
    if i:
        print(i.group(0))
re.sub()

re.sub(pattern,repl,string,count=0,flags=0)

在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串

  • pattern:正则表达式的字符串或原生字符串表示
  • repl:替换匹配字符串的字符串
  • string:待匹配字符串
  • count:匹配的最大替换次数
  • flags:正则表达式使用时的控制标记
import re
print(re.sub(r"[1-9]\d{5}",":world","BIT100081 SHS123123214345 SHDHKJ1231"))

RE库的另一种用法:

  • 函数式:一次性操作

    inport re
    match=re.search(r'[1-9]\d{5}','BIT 100081')
    
  • 面向对象:编译后的多次操作

    import re
    regex=re.compile(r"[1-9]\d{5}")
    match=regex.search("BIT 100081")
    
regex=re.compile()

regex=re.compile(pattern,flags=0)

将正则表达式的字符串形式编译成正则表达式对象

  • pattern:正则表达式的字符串或原生字符串表示
  • flags:正则表达式使用时的控制标记
Re库的match对象

​ Match对象的属性

属性说明
.string待匹配的文本
.re匹配时使用的pattern对象(正则表达式)
.pos正则表达式搜索文本的开始位置
.endpos正则表达式搜索文本的结束位置
import re
match=re.search(r'[1-9]\d{5}','BIT 100081 HDJ23323213 JDK434382')
print(".string:",match.string)
print(".re:",match.re)
print(".pos:",match.pos)
print(".endpos:",match.endpos)

​ Match对象的方法

方法说明
.group()获得匹配后的字符串
.start()匹配字符串在原始字符串的开始位置
.end()匹配字符串在原始字符串的结束位置
.span()返回(.start(),.end())
import re
match=re.search(r'[1-9]\d{5}','BIT 100081')
print(match)
if match:
    print(match.group(0))
    print(match.start())
    print(match.end())
    print(match.span())
Re库的贪婪匹配和最小匹配

贪婪匹配

Re库默认采用贪婪匹配,即输出匹配最长的子串

import re
match=re.search(r"PY.*N","PYANBNCNDN")
print(match.group(0))

最小匹配

import re
match =re.search(r"PY.*?N","PYANBNCNDN")
print(match.group(0))

​ 最小匹配操作符

操作符说明
*?前一个字符0次或无限次扩展,最小匹配
+?前一个字符1次或无限次扩展,最小匹配
??前一个字符0次或1一次扩展,最小匹配
{m,n}?扩展前一个字符m至n次(含n),最小匹配
淘宝商品信息定向爬取实例
import requests
import re
headers={
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
"cookie": "登陆后访问页面的cookie"	
}
def getHTMLText(url):
	try:
		r=requests.get(url,headers=headers,timeout=30)
		r.raise_for_status()
		r.encoding="utf-8"
		return r.text
	except:
		print("网络获取失败!")
def parsePage(ilt,html):
	try:
		plt=re.findall(r'\"view_price\"\:\"[\d.]*\"',html)
		tlt=re.findall(r'\"raw_title\"\:\".*?\"',html)
		for i in range(len(plt)):
			price=eval(plt[i].split(":")[1])
			title=eval(tlt[i].split(":")[1])
			ilt.append([price,title])
	except:
		print("网页获取失败!")
def printGoodsList(ilt):
	tplt="{:4}\t{:8}\t{:16}"
	print(tplt.format("序号","价格","商品名称"))
	count=0
	for g in ilt:
		count=count+1
		print(tplt.format(count,g[0],g[1]))

def main():
	depth=2
	start_url="https://s.taobao.com/list?spm=a217q.8031046.292818.2.3ab1789d9NSnuq&q=%E7%94%B7%E5%8C%85&cat=50072686&style=grid&seller_type=taobao&fs=1&auction_tag%5B%5D=12034"
	infoList=[]
	for i in range(depth):
		try:
			url=start_url+"&s="+str(44*i)
			html=getHTMLText(url)
			parsePage(infoList,html)
		except:
			continue
	printGoodsList(infoList)

if __name__ == '__main__':
	main()
股票定向爬虫 实例
import requests
from  bs4  import BeautifulSoup
# import traceback
import re

def getHTMLText(url):
	try:
		r=requests.get(url,timeout=30)
		r.raise_for_status()
		r.encoding="utf-8"
		return r.text
	except:
		# print("网站连接失败!")
		return ""

def getStockList(lst,stockURL):
	html=getHTMLText(stockURL)
	soup=BeautifulSoup(html,"lxml")
	a=soup.find_all('a')
	for i in a:
		try:
			href=i.attrs["href"]
			lst.append(re.findall(r"[s][hz]\d{6}",href)[0])
		except:
			continue

def getStockInfo(lst,stockURL,fpath):
	count=0
	for stock in lst:
		url=stockURL+stock +".html"
		html=getHTMLText(url)
		try:
			if html=="":
				continue
			infoDict={}
			soup=BeautifulSoup(html,"lxml")
			stockInfo=soup.find('div',attrs={'class','stock-bets'})
			name=stockInfo.find_all(attrs={'class','bets-name'})[0]
			infoDict.update({'股票名称':name.text.split()[0]})
			keyList=stockInfo.find_all('dt')
			valueList=stockInfo.find_all('dd')
			for i in range(len(keyList)):
				key=keyList[i].text
				val=valueList[i].text
				infoDict[key]=val
			with open(fpath,'a',encoding='utf-8') as f:
				f.write(str(infoDict)+'\n')
				count=count+1
				print("\r当前速度:{:.2f}%".format(count*100/len(lst),end=''))
		except:
			count=count+1
			print("\r当前速度:{:.2f}%".format(count*100/len(lst),end=''))
			continue



	return ""

def main():
	stock_list_url="http://quote.eastmoney.com/stocklist.html"
	stock_info_url="http://www.eastmoney.com/stock/"
	output_file="./output_file.txt"
	slist=[]
	getStockList(slist,stock_list_url)
	getStockInfo(slist,stock_info_url,output_file)

if __name__ == '__main__':
	main()

Scrapy爬虫框架结构

安装:pip install scrapy

image-20191208231742805.pngimage-20191208231829770.pngimage-20191208232017556.png

image-20191208232305716.png

image-20191208232657562.png
image-20191208232855000.png
在这里插入图片描述

Requests库和Scrapy框架的比较

​ Requests VS Scrapy

RequestsScrapy
页面级爬虫网站级爬虫
功能库框架
并发性考虑不足,性能差并发性好,性能较高
重点在于网页下载重点在于爬虫结构
定制灵活一般定制灵活,深度定制困难
上手十分简单入门稍难

Scrapy常用命令

命令说明格式
startproject创建一个新工程scrapy startproject [dir]
genspider创建一个爬虫scrapy genspider [options]
settings获得爬虫配置信息scrapy settings [options]
crawl运行一个爬虫scrapy crawl
list列出工程中的所有爬虫scrapy list
shell启动url调试命令行scrapy shell [url]
第一个实例

image-20191209011339530.png
image-20191209011400536.png
image-20191209011416767.png

image-20191209011501991.png

生成一个爬虫

scrapy genspider demo python123.io

image-20191209011634172.png

image-20191209011818005.png

生成的demo.py

# -*- coding: utf-8 -*-
import scrapy


class DemoSpider(scrapy.Spider):
    name = 'demo'
    allowed_domains = ['python123.io']
    start_urls = ['http://python123.io/']

    def parse(self, response):
        pass

parse()用于处理响应,解析内容形成字典,发现新的URL爬取请求

配置生成的spider爬虫:

# -*- coding: utf-8 -*-
import scrapy


class DemoSpider(scrapy.Spider):
    name = 'demo'
    # allowed_domains = ['python123.io']
    start_urls = ['http://python123.io/ws/demo.html']

    def parse(self, response):
    	fname=response.url.split('/')[-1]
    	with open(fname,'wb') as f:
    		f.write(response.body)
    	self.log('Save file %s.' % fname)
        

运行demo爬虫:

image-20191209013432909.png

在这里插入图片描述

demo.py代码的完整版本:

# -*- coding: utf-8 -*-
import scrapy

class DemoSpider(scrapy.Spider):
    name = 'demo'
    # allowed_domains = ['python123.io']
    def start_requests(self):
    	urls = ['http://python123.io/ws/demo.html']
    	for url in urls:
    		yield scrapy.Request(url=url,callback=self.parse)

    def parse(self, response):
    	fname=response.url.split('/')[-1]
    	with open(fname,'wb') as f:
    		f.write(response.body)
    	self.log('Save file %s.' % fname)

两者等价

yield关键字

image-20191209014052688.png

例子:


#生成器写法
def gen(n):
	for i in range(n):
		yield i**2

for i in gen(5):
	print(i," ",end="")

#普通写法
def square(n):
	ls=[i**2 for i in range(n)]
	return ls

for i in square(5):
	print(i," ",end="")

生成器高效快捷,占用计算资源少,可以处理大数据

scrapy的基本使用

image-20191209015519194.png

Request类

class scrapy.http.Request()

  • 表示一个http请求

  • 由Spider生成,由Downloader执行

    ​ Request类型

属性或方法说明
.urlRequest对应的请求URL地址
.method对应的请求方法,“GET”,“POST”等
.headers字典类型风格的请求头
.body请求内容主体,字符串类型
.meta用户添加的扩展信息,在Scrapy内部模块间传递信息使用
.copy()复制该请求

Response类

class scrapy.http.Response()

  • Response对象表示一个http响应

  • 由Downloader生成,由Spider处理

    ​ Response类型

属性或方法说明
.urlResponse对应的请求URL地址
.statusHTTP状态码,默认是200
.headersResponse对应的头部信息
.bodyResponse对应的内容信息,字符串类型
.flags一组标记
.request产生Response类型对应的Request对象
.copy()复制该响应

Item类

class scrapy.item.Item()

  • Item对象表示一个从HTML页面中提取的信息内容
  • 由Spider生成,由Item Pipeline处理
  • Item类似字典型,可以按照字典类型操作

Scrapy爬虫提取信息的方法

scrapy爬虫框架支持多种HTML信息提取方法

  • BeautifulSoup
  • lxml
  • re
  • XPath Selector
  • CSS Selector
股票数据scrapy爬取实例

步骤:

  • scrapy startproject BaiduStocks
  • cd BaiduStocks/
  • scrapy genspider stocks baidu.com
  • cd BaiduStocks/spiders

编写stocks.py

# -*- coding: utf-8 -*-
import scrapy
import re

class StocksSpider(scrapy.Spider):
    name = 'stocks'
    start_urls = ['http://quote.eastmoney.com/stocklist.html']

    def parse(self, response):
    	for href in response.css('a::attr(href)').extract():
    		try:
    			stock=re.findall(r"[s][hz]\d{6}",href)[0]
    			url='http://gupiao.baidu.com/stock/'+stock+'.html'
    			yield scrapy.Request(url,callback=self.parse_stock)
    		except:
    			continue
    def parse_stock(self,response):
    	infoDict={}
    	stockInfo=response.css('.stock-bets')
    	name=stocklist.css('.bets-name').extract()[0]
    	keyList=stockInfo.css('dt').extract()
    	valueList=stockInfo.css('dd').extract()
    	for i in range(len(keyList)):
    		key=re.findall(r'>.*</dt>',keyList[i])[0][1:-5]
    		try:
    			val=re.findall(r'\d+\.?.*</dd>',valueList[i])[0][0:-5]
    		except:
    			val='--'
    		infoDict[key]=val

    	infoDict.update({'股票名称':re.findall(r'\s.*\(',name)[0].split()[0]+\
    		re.findall(r'\>.*\<',name)[0][1:-1]})
    	yield infoDict

编写pipeline.py

# -*- coding: utf-8 -*-

# 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


class BaidustocksPipeline(object):
    def process_item(self, item, spider):
        return item

#自写类
class BaidustocksInfoPipeline(object):
	def open_spider(self,spider):
		self.f=open('BaidustocksInfo.txt','w')

	def close_spider(self,spider):
		self.f.close()

	def process_item(self, item, spider):
        try:
        	line=str(dict(item))+'\n'
        	self.f.write(line)
        except:
        	pass
        return item

在settings.py中配置,来调用自写类,将ITEM_PIPELINES设置如下,然后保存:

image-20191209024336534.png

配置并发连接选项

配置文件 settings.py

settings.py文件

选项说明
CONCURRENT_REQUESTSDOWnLoader最大并发请求下载数量,默认是32
CONCURRENT_ITEMSItemPipeline最大并发ITEM处理数量,默认是100
CONCURRENT_REQUESTS_PER_DOMAIN每个目标域名的最大并发请求数量,默认是8
CONCURRENT_REQUESTS_PER_IP每个目标IP的最大并发请求数量,默认是0,非0有效

  1. A-Za-z ↩︎

  2. 1-9 ↩︎

  • 9
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值