Python爬虫
2021-06-22 16:54:24 0 举报
AI智能生成
爬虫知识体系框架
作者其他创作
大纲/内容
常用操作
requests库使用
示例
import requests
response = requests.get('http://httpbin.org/get?name=lu&age=2')
print(response.text)
response = requests.get('http://httpbin.org/get?name=lu&age=2')
print(response.text)
import requests
from urllib.parse import urlencode
data = {
'name': '陆杨',
'age':22
}
response = requests.get('http://httpbin.org/get', params=urlencode(data))
print(response.text)
from urllib.parse import urlencode
data = {
'name': '陆杨',
'age':22
}
response = requests.get('http://httpbin.org/get', params=urlencode(data))
print(response.text)
urllib库使用
常用使用模块
urllib.request
urllib.error
urllib.parse
urllib.robotparser
示例
import urllib.request
url = 'http://blog.csdn.net/weiwei_pig/article/details/51178226'
file = urllib.request.urlopen(url)
print(file.getcode())
url = 'http://blog.csdn.net/weiwei_pig/article/details/51178226'
file = urllib.request.urlopen(url)
print(file.getcode())
url编码
# url编码, 用于中文以及特殊字符
encode_url = urllib.request.quote("http://www.sina.com.cn")
print(encode_url)
decode_url = urllib.request.unquote(encode_url)
print(decode_url)
encode_url = urllib.request.quote("http://www.sina.com.cn")
print(encode_url)
decode_url = urllib.request.unquote(encode_url)
print(decode_url)
设置超时
for i in range(1, 100):
try:
file = urllib.request.urlopen('http://yum.iqianyue.com', timeout=30)
data = file.read()
print(len(data))
except Exception as e:
print("出现异常-->{}".format(e))
try:
file = urllib.request.urlopen('http://yum.iqianyue.com', timeout=30)
data = file.read()
print(len(data))
except Exception as e:
print("出现异常-->{}".format(e))
urlopen()不支持一些HTTP的高级功能
所以需要修改报头
所以需要修改报头
添加header
使用build_opener()修改报头
headers = ("User-Agent",
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1")
opener = urllib.request.build_opener()
opener.addheaders = [headers]
data = opener.open(url).read()
fhandle = open('3.html', 'wb')
fhandle.write(data)
fhandle.close()
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1")
opener = urllib.request.build_opener()
opener.addheaders = [headers]
data = opener.open(url).read()
fhandle = open('3.html', 'wb')
fhandle.write(data)
fhandle.close()
使用add_header()添加报头
req = urllib.request.Request(url)
req.add_header('User-Agent',
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1")
data = urllib.request.urlopen(req).read()
print(data)
req.add_header('User-Agent',
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1")
data = urllib.request.urlopen(req).read()
print(data)
HTTP协议请求
6大种类
GET请求
构建方法
1.构建对应的URL地址,http://网址?字段名1=字段内容&字段名2=字段内容2
2.以对应的URL为参数,构建Reqeuest对象
3.通过urlopen()打开构建的Request对象
4.按需要进行后续的处理操作
2.以对应的URL为参数,构建Reqeuest对象
3.通过urlopen()打开构建的Request对象
4.按需要进行后续的处理操作
POST请求
构建方法
1.设置好URL网址
2.构架表单数据,并使用urllib.parse.urlencode对数据进行编码处理
3.创建Request对象,参数包括URL地址和要传递的数据
4.使用add_header()添加头信息,模拟浏览器进行爬取
5.使用urllib.request.urlopen()打开对应的Request对象,完成信息的传递
6.后续处理,比如读取网页内容,将内容写入文件等
2.构架表单数据,并使用urllib.parse.urlencode对数据进行编码处理
3.创建Request对象,参数包括URL地址和要传递的数据
4.使用add_header()添加头信息,模拟浏览器进行爬取
5.使用urllib.request.urlopen()打开对应的Request对象,完成信息的传递
6.后续处理,比如读取网页内容,将内容写入文件等
示例
import urllib.request
import urllib.parse
url = 'http://www.iqianyue.com/mypost/'
postdata = urllib.parse.urlencode({
"name": "ceo@iqianyue.com",
"pass": "aA123456"
}).encode('utf-8')
req = urllib.request.Request(url, postdata)
req.add_header('User-Agent',
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1")
data = urllib.request.urlopen(req).read()
fhandle = open('6.html', 'wb')
fhandle.write(data)
fhandle.close()
import urllib.parse
url = 'http://www.iqianyue.com/mypost/'
postdata = urllib.parse.urlencode({
"name": "ceo@iqianyue.com",
"pass": "aA123456"
}).encode('utf-8')
req = urllib.request.Request(url, postdata)
req.add_header('User-Agent',
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1")
data = urllib.request.urlopen(req).read()
fhandle = open('6.html', 'wb')
fhandle.write(data)
fhandle.close()
PUT请求
请求服务器存储一个资源,通常指定存储的位置
DELETE请求
请求服务器删除一个资源
HEAD请求
请求获取对应的HTTP报头信息
OPTIONS请求
获得当前URL所支持的请求类型
代理服务器
网址
代理服务器的设置
http://yum.iqianyue.com/proxy
http://yum.iqianyue.com/proxy
示例
代理服务器示例:
def use_proxy(proxy_addr, url):
import urllib.request
proxy = urllib.request.ProxyHandler({'https': proxy_addr})
# 创建一个自定义的opener对象
opener = urllib.request.build_opener(proxy,
urllib.request.HTTPHandler)
# 创建全局默认的opener对象
urllib.request.install_opener(opener)
data = urllib.request.urlopen(url).read().decode('utf-8')
return data
proxy_addr = '124.133.97.17:8118'
data = use_proxy(proxy_addr, "http://www.baidu.com")
print(len(data))
def use_proxy(proxy_addr, url):
import urllib.request
proxy = urllib.request.ProxyHandler({'https': proxy_addr})
# 创建一个自定义的opener对象
opener = urllib.request.build_opener(proxy,
urllib.request.HTTPHandler)
# 创建全局默认的opener对象
urllib.request.install_opener(opener)
data = urllib.request.urlopen(url).read().decode('utf-8')
return data
proxy_addr = '124.133.97.17:8118'
data = use_proxy(proxy_addr, "http://www.baidu.com")
print(len(data))
开启DebugLog模式
# 开启DebugLog
httphd = urllib.request.HTTPHandler(debuglevel=1)
或者
httpshd = urllib.request.HTTPSHandler(debuglevel=1)
opener = urllib.request.build_opener(proxy, httphd)
httphd = urllib.request.HTTPHandler(debuglevel=1)
或者
httpshd = urllib.request.HTTPSHandler(debuglevel=1)
opener = urllib.request.build_opener(proxy, httphd)
异常处理-URLError
原因
1.连接不上服务器
2.远程URL不存在
3.无网络
4.触发了HTTPError
2.远程URL不存在
3.无网络
4.触发了HTTPError
异常代码值
200 ok
301 Move Permanently 重定向到新的url,永久性
302 Found 重定向到临时的url,非永久性
304 not modified 请求的资源未更新
400 bad request 非法请求
401 Unauthorized 请求未经授权
403 Forbidden 禁止访问
404 not found 没有找到对应页面
500 服务器内部出现错误
501 服务器不支持实现请求所需要的功能
301 Move Permanently 重定向到新的url,永久性
302 Found 重定向到临时的url,非永久性
304 not modified 请求的资源未更新
400 bad request 非法请求
401 Unauthorized 请求未经授权
403 Forbidden 禁止访问
404 not found 没有找到对应页面
500 服务器内部出现错误
501 服务器不支持实现请求所需要的功能
示例
合并处理异常代码:
import urllib.request
import urllib.error
try:
urllib.request.urlopen('http://blog.baidusss.net')
except urllib.error.HTTPError as e:
print(e.reason)
print(e.code)
except urllib.error.URLError as e:
if hasattr(e, 'code'):
print(e.code)
if hasattr(e, 'reason'):
print(e.reason)
import urllib.request
import urllib.error
try:
urllib.request.urlopen('http://blog.baidusss.net')
except urllib.error.HTTPError as e:
print(e.reason)
print(e.code)
except urllib.error.URLError as e:
if hasattr(e, 'code'):
print(e.code)
if hasattr(e, 'reason'):
print(e.reason)
正则表达式
种类
原子
概念
原子是正则表达式的最基本的组成单位,每个正则表达式中至少要包含一个原子
种类
1.普通字符作为原子
import re
# 普通字符作为原子
pattern = 'yue'
string = "http://yum.iqianyue.com"
result1 = re.search(pattern, string)
print(result1)
# 普通字符作为原子
pattern = 'yue'
string = "http://yum.iqianyue.com"
result1 = re.search(pattern, string)
print(result1)
2.非打印字符为原子
# 常用的非打印字符, \n, \t
pattern = "\n"
string = '''http://yum.iqianyue.comhttp://baidu.com'''
result1 = re.search(pattern, string)
print(result1)
pattern = "\n"
string = '''http://yum.iqianyue.comhttp://baidu.com'''
result1 = re.search(pattern, string)
print(result1)
3.通用字符作为原子
# 通用字符作为原子
# 一个原子可以匹配一类字符
# \w 匹配任意一个字母,数字或下划线
# \W 匹配除字母,数字和下划线以外的任意一个字符
# \d 匹配任意一个十进制
# \D 匹配除十进制以外的任意一个其他字符
# \s 匹配任意一个空白字符
# \S 匹配除空白字符以外的任意一个其他字符
pattern = "\w\dpython\w"
string = 'abcdfphp345python_py'
result1 = re.search(pattern, string)
print(result1)
# 一个原子可以匹配一类字符
# \w 匹配任意一个字母,数字或下划线
# \W 匹配除字母,数字和下划线以外的任意一个字符
# \d 匹配任意一个十进制
# \D 匹配除十进制以外的任意一个其他字符
# \s 匹配任意一个空白字符
# \S 匹配除空白字符以外的任意一个其他字符
pattern = "\w\dpython\w"
string = 'abcdfphp345python_py'
result1 = re.search(pattern, string)
print(result1)
4.原子表
# 原子表
# 可以定义组地位平等的原子,然后匹配的时候会取该原子表中的任意一个原子进行匹配
pattern1 = "\w\dpython[xyz]\w"
pattern2 = "\w\dpython[^xyz]\w" #[^]代表除了括号里面的原子均可以匹配
pattern3 = "\w\dpython[xyz]\W"
string = "abcdfphp345pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
result3 = re.search(pattern3, string)
print(result1) # <_sre.SRE_Match object; span=(9, 19), match='45pythony_'>
print(result2) # None
print(result3) # Noe
# 可以定义组地位平等的原子,然后匹配的时候会取该原子表中的任意一个原子进行匹配
pattern1 = "\w\dpython[xyz]\w"
pattern2 = "\w\dpython[^xyz]\w" #[^]代表除了括号里面的原子均可以匹配
pattern3 = "\w\dpython[xyz]\W"
string = "abcdfphp345pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
result3 = re.search(pattern3, string)
print(result1) # <_sre.SRE_Match object; span=(9, 19), match='45pythony_'>
print(result2) # None
print(result3) # Noe
元字符
概念
元字符,就是正则表达式中具有一些特殊含义的字符,比如重复N次前面的字符等
常见的元字符以其含义
. 匹配除换行符以外的任意字符
^ 匹配字符串的开始位置
$ 匹配字符串的结束位置
* 匹配0次,1次或多次前面的原子
? 匹配0次或1次前面的原子
+ 匹配1次或多次前面的原子
{n} 前面的原子恰好出现n次
{n,}前面的原子至少出现n次
{n,m} 前面的原子至少出现n次,至多出现m次
| 模式选择符
() 模式单元符
常见的元字符以其含义
. 匹配除换行符以外的任意字符
^ 匹配字符串的开始位置
$ 匹配字符串的结束位置
* 匹配0次,1次或多次前面的原子
? 匹配0次或1次前面的原子
+ 匹配1次或多次前面的原子
{n} 前面的原子恰好出现n次
{n,}前面的原子至少出现n次
{n,m} 前面的原子至少出现n次,至多出现m次
| 模式选择符
() 模式单元符
示例
种类
限定符
# 限定符
# 常见的限定符号*,?,+,{n},{n,},{n,m}
print()
import re
pattern1 = "py.*n"
pattern2 = "cd{2}"
pattern3 = "cd{3}"
pattern4 = "cd{2,}"
string = "abcdddfphp345pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
result3 = re.search(pattern3, string)
result4 = re.search(pattern4, string)
print(result1)
print(result2)
print(result3)
print(result4)
# 常见的限定符号*,?,+,{n},{n,},{n,m}
print()
import re
pattern1 = "py.*n"
pattern2 = "cd{2}"
pattern3 = "cd{3}"
pattern4 = "cd{2,}"
string = "abcdddfphp345pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
result3 = re.search(pattern3, string)
result4 = re.search(pattern4, string)
print(result1)
print(result2)
print(result3)
print(result4)
边界限制元字符
# 边界限制元字符
# 使用^匹配字符串开始,使用$匹配字符串的结束
pattern1 = "^abd" # 必须以abd开头
pattern2 = "^abc" # 必须以abc开头
pattern3 = "py$" # 必须以py结尾
pattern4 = "ay$" # 必须以ay结尾
string = "abcdfphp345pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
result3 = re.search(pattern3, string)
result4 = re.search(pattern4, string)
print(result1)
print(result2)
print(result3)
print(result4)
if result1 is None:
print("result1 is none")
# 使用^匹配字符串开始,使用$匹配字符串的结束
pattern1 = "^abd" # 必须以abd开头
pattern2 = "^abc" # 必须以abc开头
pattern3 = "py$" # 必须以py结尾
pattern4 = "ay$" # 必须以ay结尾
string = "abcdfphp345pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
result3 = re.search(pattern3, string)
result4 = re.search(pattern4, string)
print(result1)
print(result2)
print(result3)
print(result4)
if result1 is None:
print("result1 is none")
常见的元字符
import re
pattern = '.python...' # 前面有1位,后面有3位格式的字符(除了换行符以外任意字符)
string = "abcdfphp345python_py"
result1 = re.search(pattern, string)
print(result1)
pattern = '.python...' # 前面有1位,后面有3位格式的字符(除了换行符以外任意字符)
string = "abcdfphp345python_py"
result1 = re.search(pattern, string)
print(result1)
模式选择符
# 模式选择符
import re
pattern = "python|php" #python和php均满足条件
string = "abcdfphp345pythony_py"
result1 = re.search(pattern, string)
print(result1)
import re
pattern = "python|php" #python和php均满足条件
string = "abcdfphp345pythony_py"
result1 = re.search(pattern, string)
print(result1)
模式单元符
# 模式单元符
pattern1 = "(cd){1,}" #cd整体至少出现1次,会尽可能多的匹配
pattern2 = "cd{1,}" #d原子至少出现1次
string = "abcdcdcdcdfphp345pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
print(result1) #<_sre.SRE_Match object; span=(2, 10), match='cdcdcdcd'>
print(result2) #<_sre.SRE_Match object; span=(2, 4), match='cd'>
pattern1 = "(cd){1,}" #cd整体至少出现1次,会尽可能多的匹配
pattern2 = "cd{1,}" #d原子至少出现1次
string = "abcdcdcdcdfphp345pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
print(result1) #<_sre.SRE_Match object; span=(2, 10), match='cdcdcdcd'>
print(result2) #<_sre.SRE_Match object; span=(2, 4), match='cd'>
模式修正
概念
模式修正
可以在不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,
从而实现一些匹配结果的调整
I 匹配时候忽略大小写
M 多行匹配
L 做本地化识别匹配
U 根据Unicode字符及解析字符
S 让.匹配包括换
可以在不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,
从而实现一些匹配结果的调整
I 匹配时候忽略大小写
M 多行匹配
L 做本地化识别匹配
U 根据Unicode字符及解析字符
S 让.匹配包括换
示例
import re
pattern1 = "python"
pattern2 = "python"
string = "abcdfphp345Pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string, re.I)
print(result1) #None
print(result2) #<_sre.SRE_Match object; span=(11, 17), match='Python'>
pattern1 = "python"
pattern2 = "python"
string = "abcdfphp345Pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string, re.I)
print(result1) #None
print(result2) #<_sre.SRE_Match object; span=(11, 17), match='Python'>
贪婪模式与懒惰模式
概念
贪婪模式
尽可能多地匹配
懒惰模式
尽可能少地匹配
示例
# 贪婪模式,懒惰模式
import re
pattern1 = "p.*y" # 贪婪模式 默认使用贪婪模式
pattern2 = "p.*?y" # 懒惰模式 在.*后面加上?
string = "abcdfphp345pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
print(result1) #<_sre.SRE_Match object; span=(5, 21), match='php345pythony_py'>
print(result2) #<_sre.SRE_Match object; span=(5, 13), match='php345py'>
import re
pattern1 = "p.*y" # 贪婪模式 默认使用贪婪模式
pattern2 = "p.*?y" # 懒惰模式 在.*后面加上?
string = "abcdfphp345pythony_py"
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
print(result1) #<_sre.SRE_Match object; span=(5, 21), match='php345pythony_py'>
print(result2) #<_sre.SRE_Match object; span=(5, 13), match='php345py'>
常见函数
种类
re.match()函数
从源字符串的开头进行匹配
import re
string = "apythonhellomypythonhispythonourpythonend"
pattern = ".python."
result = re.match(pattern, string)
result2 = re.match(pattern, string).span()
print(result) #<_sre.SRE_Match object; span=(0, 8), match='apythonh'>
print(result2) #(0, 8)
string = "apythonhellomypythonhispythonourpythonend"
pattern = ".python."
result = re.match(pattern, string)
result2 = re.match(pattern, string).span()
print(result) #<_sre.SRE_Match object; span=(0, 8), match='apythonh'>
print(result2) #(0, 8)
.re.search()函数
会在全文中进行检索匹配
import re
string = "pythonhellomypythonhispythonourpythonend"
pattern = ".python."
result = re.match(pattern, string) # 从源字符串的开头进行匹配
result2 = re.search(pattern, string) # 会在全文中进行检索匹配
print(result) #None
print(result2) #<_sre.SRE_Match object; span=(12, 20), match='ypythonh'>
string = "pythonhellomypythonhispythonourpythonend"
pattern = ".python."
result = re.match(pattern, string) # 从源字符串的开头进行匹配
result2 = re.search(pattern, string) # 会在全文中进行检索匹配
print(result) #None
print(result2) #<_sre.SRE_Match object; span=(12, 20), match='ypythonh'>
全局匹配函数
方法
全局匹配函数
源字符串中有多个结果符合模式,希望符合模式的内容全部都匹配出来
1.使用re.complie()对正则表达式进行预编译
2.编译后,使用finall()根据正则表达式从源字符串中将匹配的结果全部找出
源字符串中有多个结果符合模式,希望符合模式的内容全部都匹配出来
1.使用re.complie()对正则表达式进行预编译
2.编译后,使用finall()根据正则表达式从源字符串中将匹配的结果全部找出
示例
import re
string = "hellomypythonhispythonourpythonend"
pattern = re.compile(".python.") #预编译
result = pattern.findall(string) # 找出符合模式的所有结果
print(result) #['ypythonh', 'spythono', 'rpythone']
string = "hellomypythonhispythonourpythonend"
pattern = re.compile(".python.") #预编译
result = pattern.findall(string) # 找出符合模式的所有结果
print(result) #['ypythonh', 'spythono', 'rpythone']
re.sub函数
根据正则表达式来实现替换某些字符串的功能
import re
string = "hellomypythonhispythonoutpythonend"
pattern = "python."
result1 = re.sub(pattern, "php", string) #全部替换
result2 = re.sub(pattern, "php", string, 2) #最多地替换2次
print(result1) #hellomyphpisphputphpnd
print(result2) #hellomyphpisphputpythonend
string = "hellomypythonhispythonoutpythonend"
pattern = "python."
result1 = re.sub(pattern, "php", string) #全部替换
result2 = re.sub(pattern, "php", string, 2) #最多地替换2次
print(result1) #hellomyphpisphputphpnd
print(result2) #hellomyphpisphputpythonend
示例
网址匹配
# 匹配网址
import re
pattern = "[a-zA-Z]+://[^\s]*[.com|.cn]"
string = "<\a href='http://www.baidu.com'>百度首页<\/a>"
result = re.search(pattern, string)
print(result)
#<_sre.SRE_Match object; span=(9, 29), match='http://www.baidu.com'>
import re
pattern = "[a-zA-Z]+://[^\s]*[.com|.cn]"
string = "<\a href='http://www.baidu.com'>百度首页<\/a>"
result = re.search(pattern, string)
print(result)
#<_sre.SRE_Match object; span=(9, 29), match='http://www.baidu.com'>
匹配电话号码
import re
pattern = "\d{4}-\d{7}|\d{3}-\d{8}" # 匹配电话号码的正则表达式
string = "021-672826353682382265236"
result = re.search(pattern, string)
print(result)
#<_sre.SRE_Match object; span=(0, 12), match='021-67282635'>
pattern = "\d{4}-\d{7}|\d{3}-\d{8}" # 匹配电话号码的正则表达式
string = "021-672826353682382265236"
result = re.search(pattern, string)
print(result)
#<_sre.SRE_Match object; span=(0, 12), match='021-67282635'>
匹配电子邮件
import re
pattern = "\w+([.+-]\w+)*@\w+([.-]\w+)*\.\w+([.-]\w+)*"
string = "<\a href='http://www.baidu.com'>百度首页<\/a>
<\a href='mailto:c-e+o@iqi-anyue.com.cn'>电子邮件地址<\/a>"
result = re.search(pattern, string)
print(result)
#<_sre.SRE_Match object; span=(59, 81), match='c-e+o@iqi-anyue.com.cn'>
pattern = "\w+([.+-]\w+)*@\w+([.-]\w+)*\.\w+([.-]\w+)*"
string = "<\a href='http://www.baidu.com'>百度首页<\/a>
<\a href='mailto:c-e+o@iqi-anyue.com.cn'>电子邮件地址<\/a>"
result = re.search(pattern, string)
print(result)
#<_sre.SRE_Match object; span=(59, 81), match='c-e+o@iqi-anyue.com.cn'>
re库正则表达式使用
对字符串的一种过滤逻辑
示例
需要信息在js中,使用正则表达式
解析日志信息使用正则表达式
Cookie
原因
HTTP协议是无状态协议,(无状态协议即无法维持会话之间的状态)
保存信息方法
Cookie保存会话
Session保存会话信息
Python版本
在Python3中使用Cookiejar库进行处理
在Python2中使用Cookielib库进行处理
在Python2中使用Cookielib库进行处理
常用思路
1.导入Cookie处理模块http.cookiejar
2.使用http.cookiejar.CookieJar()创建CookieJar对象
3.使用HTTPCookieProcessor创建cookie处理器,并以其为参数构建opener对象
4.创建全局默认的opener对象
2.使用http.cookiejar.CookieJar()创建CookieJar对象
3.使用HTTPCookieProcessor创建cookie处理器,并以其为参数构建opener对象
4.创建全局默认的opener对象
示例
# 希望登录状态一直保持,使用Cookie处理
import http.cookiejar
# 使用http.cookiejar.CookieJar()创建CookieJar对象
cjar = http.cookiejar.CookieJar()
# 使用HTTPCookieProcessor创建cookie处理器,并以其为参数构建opener对象
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cjar))
# 将opener安装为全局
urllib.request.install_opener(opener)
import http.cookiejar
# 使用http.cookiejar.CookieJar()创建CookieJar对象
cjar = http.cookiejar.CookieJar()
# 使用HTTPCookieProcessor创建cookie处理器,并以其为参数构建opener对象
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cjar))
# 将opener安装为全局
urllib.request.install_opener(opener)
多线程爬虫
利用线程来实现
浏览器伪装技术
反爬机制
第一种:
一般来说,大部分饭爬虫的网站会对用户请求的Headers信息,
’User-Agent’字段进行检测,以此判断用户的身份,
还会对Referer字段进行检测
一般来说,大部分饭爬虫的网站会对用户请求的Headers信息,
’User-Agent’字段进行检测,以此判断用户的身份,
还会对Referer字段进行检测
第二种:
可以通过之前使用代理服务器并经常切换代理服务器方式
可以通过之前使用代理服务器并经常切换代理服务器方式
第三种:
利用一些工具,比如selenium+phantomJS,
利用一些工具,比如selenium+phantomJS,
各字段解析
Headers字段:
Accept:表示浏览器能够支持的内容类型有哪些
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8(q是权重系数,0到1之间)
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8(q是权重系数,0到1之间)
Accept-Encoding
表示浏览器支持的压缩编码有哪些
gzip,deflate(一种无损数据压缩算法)
gzip,deflate(一种无损数据压缩算法)
Accept-Language
表示浏览器所支持的预览类型
en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
User-Agent
表示用户代理,服务器可以通过该字段识别出客户端的浏览器类型,版本,客户端操作系统以及版本号,也买呢排版引擎客户端信息
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36
Connection
表示客户端与服务器的连接类型
keep-alive表示持久性连接
close表示单方面关闭连接,让连接断开
keep-alive表示持久性连接
close表示单方面关闭连接,让连接断开
Host
表示请求的服务器网址
Referer
表示来源网址地址
示例
headers = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36",
"Connection": "keep-alive",
"referer": "http://www.163.com/",
"Accept-Encoding": "utf-8"}
其中Accept-Encoding: 如果设置gzip, deflate可能会出现乱码问题,只需要设置成utf-8
"Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36",
"Connection": "keep-alive",
"referer": "http://www.163.com/",
"Accept-Encoding": "utf-8"}
其中Accept-Encoding: 如果设置gzip, deflate可能会出现乱码问题,只需要设置成utf-8
框架实现
常见框架
Scrapy
在项目中避免被禁止
禁止Cookie
设置下载延时
使用IP池
使用用户代理池
其他方法,比如进行分布式爬取等
主要组件
工作流
Crawley
Portia
newspaper
python-goose
基础知识
基础知识
名称
网络机器人
网络蜘蛛
网络蚂蚁
作用
请求网站并提取数据的自动化程序
监测和分析,数据采集和整理
优化搜索引擎
私人订制一个搜索引擎
组成
控制节点
爬虫节点
资源库构成
爬虫种类
通用网络爬虫
组成
初始URL集合
URL队列
页面爬行模块
页面分析模块
页面数据库
链接过滤模块
特点
用于大型搜索引擎
爬取海量数据
图示
聚焦网络爬虫
组成
初始URL集合
URL队列
页面爬行模块
叶页面分析模块
页面数据库
链接过滤模块
内容评价模块
链接评价模块
特点
按照预定好的主题有选择地进行网页爬取
图示
实现流程
爬行策略
基于内容评价
基于链接评价
基于增强学习
基于语境图
增量式网络爬虫
特点
在更新的时候只更新改变的地方,而未改变的地方则不更新
深层网络爬虫
分类
基于领域知识的表单填写
基于网页结构分析的表单填写
特点
需要想办法自动填写好对应的表单
爬行策略
深度优先爬行
广度优先爬行
大站优先策略
反链策略
实现原理
第一步
获取初始化的URL,初始的URL地址可以由用户人为地指定,可以由用户指定的某个或某几个初始爬取网页决定
获取初始化的URL,初始的URL地址可以由用户人为地指定,可以由用户指定的某个或某几个初始爬取网页决定
第二步
根据初始的URL爬取页面并获得新的URL,获得初始的URL地址之后,首先需要爬取对应URL地址中的网页,爬取了对应的URL地址中的网页后,将网页存储到原始数据库中,并且在爬取网页的同时,发现新的URL地址,同时将已爬取的URL地址存放在一个URL列表中,用于去重及判断爬取的进程
根据初始的URL爬取页面并获得新的URL,获得初始的URL地址之后,首先需要爬取对应URL地址中的网页,爬取了对应的URL地址中的网页后,将网页存储到原始数据库中,并且在爬取网页的同时,发现新的URL地址,同时将已爬取的URL地址存放在一个URL列表中,用于去重及判断爬取的进程
第三步
将新的URL放到URL队列中,第2步中,获取了下一个新的URL地址之后,会将新的URL地址放到URL队列中
将新的URL放到URL队列中,第2步中,获取了下一个新的URL地址之后,会将新的URL地址放到URL队列中
第四步
从URL队列中读取新的URL,并依据新的URL爬取网页,同时从新网页中获取新的URL,并重复上述的爬取过程
从URL队列中读取新的URL,并依据新的URL爬取网页,同时从新网页中获取新的URL,并重复上述的爬取过程
第五步
满足爬虫系统设置的停止条件,停止爬取
满足爬虫系统设置的停止条件,停止爬取
图示
基本流程
第一步
发起请求
发起请求
request组成部分
请求方式
Get
Post
请求URL
请求header
配置信息等
请求体
post请求
formdata形式
第二步
获取响应内容
获取响应内容
response组成部分
响应状态
响应头
响应体
第三步
解析内容
解析内容
抓取的数据类型
网页文本
图片,视频
其他
解析方式
直接处理
json解析
正则表达式
xpath
beautifulsoup
怎么解决JavaScript渲染的问题
分析ajax请求
返回json的字符串
Selenium/WebDriver
模拟用浏览器加载网页
Splash
类似Selenium
pyv8,ghostpy
第四步
保存数据
保存数据
文本类型
纯文本
json,xml
关系型数据库
mysql
非关系型数据库
mongodb
key,value形式
其他
网页更新策略
用户体验策略
历史数据策略
类聚分析策略
网页分析算法
基于用户行为
基于网络拓扑
基于网页粒度
基于网页块粒度
基于网站粒度
基于网页内容
身份识别
Robots.txt文件来确定爬取的网页范围
通过HTTP请求中的User Agent字段告知自己的身份信息
爬取技术
定向爬取
定向爬取
解决的问题
1.清晰地定义好爬虫的爬取目标,规划好主题
2.建立好爬取网址的过滤筛选规则以及内容的过滤筛选规则
3.建立好URLP排序算法,让爬虫能够明确有限爬取那些网页,以顺序爬取待爬取的网页
主要步骤
1.理清爬取的目的
2.设置网址的规律规则
3.设好内容采集规则
4.规划好采集任务
5.将采集结果进行相应的修正
6.对结果进行进一步处理,完成任务
图示
主要策略
1.通过正则表达式筛选
2.通过XPath表达式筛选
3.通过xslt筛选
收藏
收藏
0 条评论
下一页