所谓爬虫,其实就是向网站发起请求,获取资源后分析并提取有用数据的程序,就像模拟浏览器访问网页一样,爬虫是选择获得需要的数据。
爬虫的步骤可分为以下几步:
1、发起请求
使用http库向目标站点发起请求,即发送一个Request
Request包含:请求头、请求体等
2、获取响应内容
如果服务器能正常响应,则会得到一个Response
Response包含:html,json,图片,视频等
3、解析内容
解析html数据:可以利用正则表达式,第三方解析库如Beautifulsoup,pyquery等
解析json数据:json模块
解析二进制数据:以b的方式写入文件(图片和视频)
4、保存数据
数据库、文件
这里涉及到HTTP协议和一些网络知识,可以自己网页查询。
用Python爬虫,还要了解一下几个包
- requests
requests库是一个常用的用于http请求的模块。安装命令 conda install requests 。最好使用anaconda,会将相关的包都更新安装
requests 主要方法:
方法 | 解释 |
---|---|
requests.request() | 构造一个请求,支持以下各种方法 |
requests.get() | 获取html的主要方法 |
requests.head() | 获取html头部信息的主要方法 |
requests.post() | 向html网页提交post请求的方法 |
requests.put() | 向html网页提交put请求的方法 |
requests.patch() | 向html提交局部修改的请求 |
requests.delete() | 向html提交删除请求 |
遇到一个报错:安装后pycharm报
Traceback (most recent call last):
File "E:/pythonpro/Demo/Spider.py", line 1, in <module>
import requests
ModuleNotFoundError: No module named 'requests'
解决方法:依次选择【File】-【Settings】,找到当前的项目,选择【Project Interpreter】,在右边的列表里可以看到已经安装的各种库、对应的版本以及最新版本,然后点击 + 号,搜索报错的那个库,比如本文的 requests 库,选中后点击【Install Package】安装库,安装成功后右下角会有提示 Packages installed successfully,再次运行程序就没有报错了!
补:其实把Project Interpreter切换到安装了requests的环境就可以了。上一段基础代码,requests方法具体参数构成下一章讲解
import requests
#requests 请求及response返回
response = requests.get('http://www.baidu.com/')
print(response.status_code) #http请求的返回状态,若为200则表示请求成功。
print(type(response.text))
print(response.text) #http响应内容的字符串形式,即返回的页面内容
print(response.encoding) #http响应内容的内容编码 输出:ISO-8859-1
print(response.cookies)#输出:<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
- urllib
urllib也是一个HTTP请求库,也可以进行request操作,可以看成是Java的url方式。也常用urllib进行特殊字符编码。
import urllib.request
import urllib.parse
url = 'http://www.baidu.com'
header = {}
header['User-Agent'] = 'Mozilla/5.0 ' \
'(Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 ' \
'(KHTML, like Gecko) Version/5.1 Safari/534.50'
req = urllib.request.Request(url=url, headers=header) # 动态添加也同样req.add_header('User-Agent','...')
response = urllib.request.urlopen(req)
print(response.status) # 打印状态码信息 其方法和response.getcode() 一样 都是打印当前response的状态码
print(response.getheaders()) # 打印出响应的头部信息,内容有服务器类型,时间、文本内容、连接状态等等
print(response.getheader('Server')) # 这种拿到响应头的方式需要加上参数,指定你想要获取的头部中那一条数据
print(response.geturl()) # 获取响应的url
# print(response.read())#使用read()方法得到响应体内容,这时是一个字节流bytes,看到明文还需要decode为charset格式
wd = '测试'
p = urllib.parse.urlencode({'wd': wd, 'pn': 10}) #中文编码
url = 'https://www.baidu.com/s?%s&pn=10' % p #输出结果:https://www.baidu.com/s?wd=%E6%B5%8B%E8%AF%95&pn=10&pn=10
print(url)
- re
re包下载python的时候已经安装好,可直接使用。这个包是关于正则表达式的,在爬虫中用的很广泛
import re
ret = re.findall('a', 'eva egon yuan') # 返回所有满足匹配条件的结果,放在列表里
print(ret) # 结果 : ['a', 'a']
ret = re.search('a', 'eva egon yuan').group()
print(ret) # 结果 : 'a'
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
ret = re.match('a', 'aabc').group() # 同search,不过仅在字符串开始处进行匹配,如果开始没有匹配到就报错
print(ret)
# 结果 : 'a'
ret = re.split('a', 'abcd') # 按'a'分割
print(ret) # ['', 'bcd']
ret = re.split('[ab]', 'abcd') # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret) # ['', '', 'cd']
ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1) # 将数字替换成'H',参数1表示只替换1个
print(ret) # evaHegon4yuan4
ret = re.subn('\d', 'H', 'eva3egon4yuan4') # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret) # ('evaHegonHyuanH', 3)
obj = re.compile('\d{3}') # 将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') # 正则表达式对象调用search,参数为待匹配的字符串
print(ret.group()) # 结果 : 123
ret = re.finditer('\d', 'ds3sy4784a') # finditer返回一个存放匹配结果的迭代器
print(ret) # <callable_iterator object at 0x10195f940>
print(next(ret).group()) # 查看第一个结果即3
print(next(ret).group()) # 查看第二个结果即4
print([i.group() for i in ret]) # 查看剩余的结果,以列表的形式打印,即['7', '8', '4']
具体正则需要另外百度学习。
- os
os包是关于是与操作系统交互的。删除新建文件、获取路径都可以用这个包下的方法实现。
import os
print(os.getcwd()) #获取当前工作目录,即当前python脚本工作的目录路径 结果:E:\pythonpro\Demo
print(os.path.abspath('.')) #获取当前工作目录路径 结果:E:\pythonpro\Demo
print(os.path.abspath('new.txt')) #结果:E:\pythonpro\Demo\new.txt
#os.chdir("dirname") #改变当前脚本工作目录;相当于shell下cd
print(os.curdir) #返回当前目录: ('.')
print(os.pardir) #获取当前目录的父目录字符串名:('..')
#os.makedirs('dirname1/dirname2') #可生成多层递归目录
#os.removedirs('dirname1') #若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
#os.mkdir('dirname') #生成单级目录;相当于shell中mkdir dirname
#os.rmdir('dirname') #删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
#os.listdir('dirname') #列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
#os.remove() #删除一个文件
#os.rename("oldname","newname") #重命名文件/目录