理论基础篇
第一章 什么是网络爬虫
1.网络爬虫的类型
- 通用网络爬虫:目标资源在全互联网上
- 聚焦网络爬虫:目标资源在定义好主题的互联网上
- 增量式网络爬虫:扒取新更新的页面
- 深层网络爬虫:爬取深层网页,如需要输入账号密码
2.网络爬虫技能总览
- 搜索引擎
- 爬取图片
- 爬取网站用户公开的信息进行分析
- 爬取用户公开的联系方式,进行营销
- 自动去页面广告
- 爬取多站新闻,集中阅读
- 爬取金融信息,进行投资分析
核心技术篇
第二章 网络爬虫实现原理与实现技术
1.通用网络爬虫
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-51Wl3hzM-1594820525739)(2020-07-15-07-07-39.png)]
2.聚焦网络爬虫
- 聚焦网络爬虫,由于其需要有目的地进行爬取,所以对于通用网络爬虫来说,必须要增加目标的定义和过滤机制。
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WCKhhhBw-1594820525742)(2020-07-15-07-14-26.png)]
3.身份识别
有些爬虫会伪装成其他爬虫或浏览器去爬取网站,以获得一些额外数据,或者有写爬虫,会无视Robots协议的限制而任意爬取。
第三章 Urllib库与URLError异常处理
1.快速使用Urllib爬取页面
import urllib.request
url1 = "https://www.baidu.com"
url2 = 'https://www.python.org'
response = urllib.request.urlopen(url1)
print(response.read().decode('utf-8'))
# 查看response是什么类型的数据
print(type(response))
# 响应状态码
print(response.status)
# 响应头
print(response.getheaders())
# 响应头的某一个具体信息
print(response.getheader('Content-Type'))
import urllib.request
url="https://blog.csdn.net/qq_40258748/category_8810021.html"
file = urllib.request.urlopen(url)
data=file.read()
print(data)
fhandle=open("C:/Users/29190\Desktop/软件编程/爬虫实战/csdn.html",'wb')
fhandle.write(data)
fhandle.close()
2.Headers属性
- 使用build_opener()修改报头
import urllib.request
url = "http://blog.csdn.net/qq_40258748/category_8810021.html"
#header要用(...,...)而不是requests库里面headers是字典
header = ("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64;"
" x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.159 Safari/537.36")
opener = urllib.request.build_opener()
opener.addheaders = [header]
data = opener.open(url).read()
print(data)
- 使用add_header()添加报头
import urllib.request
url = "http://blog.csdn.net/qq_40258748/category_8810021.html"
req = urllib.request.Request(url)
req.add_header ("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64;"
" x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.159 Safari/537.36")
data=urllib.request.urlopen(req).read()
print(data)
3.超时设置
有的时候,我们访问一个网页,如果该网页长时间未响应,那么系统就会判断该网页超时了。
import urllib.request
for i in range(1,100):
try:
file=urllib.request.urlopen("https://www.baidu.com",timeout=0.5)
data=file.read()
print(len(data))
except Exception as e:
print("出现异常-->"+str(e))
4.HTTP协议请求实战
HTTP协议请求主要分为6种类型
- (1)GET请求
GET请求会通过URL网址传递信息,可以直接在URL中写上要传递的信息,也可以由表单进行传递。
import urllib.request
keywd="Hello"
url="https://www.baidu.com/s?wd="+keywd
req=urllib.request.Request(url)
data=urllib.request.urlopen(req).read()
print(data)
- (2)POST请求
可以向服务器提交数据,是一种比较主流也比较安全的数据传递方式,比如在登录时,经常使用POST请求发送数据。
我们在进行注册、登录等操作的时候,基本上都会遇到POST请求。
POST请求实现的思路如下:- 1>设置好URL网址。
- 2>构建表单数据,并使用urllib.parse.urlencode对数据进行编码处理。
- 3>创建Request对象,参数包括URL地址和要传递的数据。
- 4>使用add_header()添加头信息,模型浏览器进行爬取。
- 5>urllib.requests.urlopen()打开对应的Request对象,完成信息的传递。
- 6>后续处理,比如读取网页内容、将内容写入文件等。
url = "http://www.iqianyue.com/mypost/"
postdata = urllib.parse.urlencode({
"name": "ceo@iqianyue.com",
"pass": "aA123456"
}).encode('utf-8') # 将数据使用urlencode编码处理后,使用encode()设置为utf-8
req=urllib.request.Request(url,postdata)
req.add_header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64;"
" x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.159 Safari/537.36")
data=urllib.request.urlopen(req).read()
fhandle=open("C:/Users/29190/Desktop/软件编程/爬虫实战/6.html","wb")
fhandle.write(data)
fhandle.close()
- (3)PUT请求
请求服务器存储一个资源,通常要指定存储的位置。 - (4)DELETE请求
请求服务器删除一个资源。 - (5)HEAD请求
请求获取对应的HTTP报头信息。 - (6)OPTIONS请求
可以获得当前URL所支持的请求类型。
5.代理服务器的设置
有时使用用一个IP去爬取同一个网站上的页面,久了之后会被该网站服务器屏蔽。使用代理IP,就可以解决了。
第4章正则表达式与Cookie的使用
- 有时候我们在进行字符串处理的时候,希望按自定义的规则进行处理,我们将这些规则称为模式。我们可以用正则表达式来描述这些规则,正则表达式也称为模式表达式。在Python中,一般我们会使用re模块实现Pyhton正则表达式的功能。
正则表达式基础知识
我们将分别从原子、元字符、模式修正符、贪婪模式与懒惰模式等方面介绍。
原子
- 普通字符作为原子
import re
pattern="yue" #普通字符做原子
string="http://yum.iqianyue.com"
result1=re.search(pattern,string)
print(result1)
- 非打印字符作为原子
常用的非打印字符:\n,\t
mport re
pattern= "\n"
string='''http://yum.iqianyue.com
http://baidu.com'''
result1=re.search(pattern,string)
print(result1)
- 通用字符作为原子
所谓的通用字符及其含义如图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wFkQjlIp-1594820525744)(2020-07-15-16-11-53.png)]
我们可以用"\w\dpython\w"对"python"字符进行匹配,如"67pyhton8"、"u2pyhton_"均可匹配成功。
import re
pattern= "\w\dpython\w"
string="abcdfphp345pythony_py"
result1=re.search(pattern,string)
print(result1)
- 原子表
使用原子表,可以定义一组地位平等的原子,然后匹配的时候回去该原子表中的任意一个原子进行匹配,在python中,原子表由[]表示,比如[xyz]
[^]代表的是除了括号中里面的原子均可以匹配,比如"[^xyz]py"能匹配"apy"
mport re
pattern1="\w\dpython[xyz]\w" #如果string中有[]
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)
print(result2)
print(result3)
元字符
所谓元字符,就是正则表达式中国具有一些特殊含义的字符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5flabK0P-1594820525747)(2020-07-15-16-35-47.png)]
- 任意匹配元字符
我们可以使用"."匹配一个除换行符以外的任意字符
import re
pattern=".python..."
string="abcdfphp345pythony_py"
result=re.search(pattern,string)
print(result)
- 边界限制元字符
可以用"^“匹配字符串的开始,使用”$"匹配字符串的结束
import re
pattern=["^abd","^abc","py$","ay$"]
string="abcdfphp345pythony_py"
for i in range(4):
name="result"+str(i+1)
locals()[name]=re.search(pattern[i],string) #生成动态变量
print(locals()[name])
- 限定符
import re
pattern=["py.*n","cd{2}","cd{3}","cd{2,}"]
string="abcdddfphp345pythony_py"
for i in range(4):
name="result"+str(i+1)
locals()[name]=re.search(pattern[i],string)
print(locals()[name])
- 模式选择符
模式选择符"|"可以设置多个模式,匹配时,可以从中选择任意一个模式匹配。 - 模式单元符
可以使用’()'将一些原子组合成一个大原子使用,小括号括起来的部分会被当做一个整体使用
import re
pattern=["(cd){1,}","cd{1,}"]
string="abcdcdcdcdfphp345pythony_py"
for i in range(2):
name="result"+str(i+1)
locals()[name]=re.search(pattern[i],string)
print(locals()[name])
模式修正
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rqTQm8C0-1594820525748)(2020-07-15-21-35-37.png)]
import re
pattern=["python","python"]
string="abcdcdcdcdfphp345Pythony_py"
for i in range(2):
name="result"+str(i+1)
locals()[name]=re.search(pattern[i],string,re.I)
print(locals()[name])
贪婪模式与懒惰模式
import re
pattern=["p.*y","p.*?y"] #贪婪算法 #懒惰算法
string="abcdfphp345pythony_py"
for i in range(2):
name="result"+str(i+1)
locals()[name]=re.search(pattern[i],string,re.I)
print(locals()[name])
locals()[name])
贪婪模式与懒惰模式
import re
pattern=["p.*y","p.*?y"] #贪婪算法 #懒惰算法
string="abcdfphp345pythony_py"
for i in range(2):
name="result"+str(i+1)
locals()[name]=re.search(pattern[i],string,re.I)
print(locals()[name])