爬虫——urllib爬虫模块
网络爬虫也称为网络蜘蛛、网络机器人,抓取网络的数据。
爬虫分类
1、通用网络爬虫:搜索引擎使用,遵守robots协议(君子协议)
robots协议 :网站通过robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。https://www.taobao.com/robots.txt
2、聚焦网络爬虫 :自己写的爬虫程序
爬虫爬取数据步骤
1、确定需要爬取的URL地址
2、由请求模块向URL地址发出请求,并得到网站的响应
3、从响应内容中提取所需数据
1、所需数据,保存
2、页面中有其他需要继续跟进的URL地址,继续第2步去发请求,如此循环
请求模块
from urllib import request
request.urlopen() 向网站发起请求并获取响应对象
参数:
- URL:需要爬取的URL地址
- timeout: 设置等待超时时间,指定时间内未得到响应抛出超时异常
响应对象(response)方法
- string = response.read().decode(\’utf-8\’) 获取响应对象内容(网页源代码),返回内容为字节串bytes类型,顺便需要decode转换成string。
- url = response.geturl() 返回实际数据的URL地址
- code = response.getcode() 返回HTTP响应码
from urllib import request url = \'http://www.baidu.com/\' # 向百度发请求,得到响应对象 response = request.urlopen(url) # 返回网页源代码 print(response.read().decode(\'utf-8\')) # 返回http响应码 print(response.getcode()) # 200 # 返回实际数据URL地址 print(response.geturl()) # http://www.baidu.com/
urllib.request.Request() 创建请求对象(包装请求,重构User-Agent,使程序更像正常人类请求)
参数
- URL:请求的URL地址
- headers:添加请求头(爬虫和反爬虫斗争的第一步)
使用流程
1、创建请求对象(重构User-Agent)
req = urllib.request.Request(url=url,headers={\’User-Agent\’:\’Mozilla/5.0 xxxx\’})
2、请求对象发起请求,获取响应对象(urlopen)
res = urllib.request.urlopen(req)
3、通过相应对象获取响应内容
html = res.read().decode(\’utf-8\’)
from urllib import request url = \'http://httpbin.org/get\' headers = {\'User-Agent\':\'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3)\'} # 创建请求对象(包装请求) req = request.Request(url=url,headers=headers) # 发请求,获取响应对象 res = request.urlopen(req) # 读取内容,返回网页代码 html = res.read().decode(\'utf-8\') print(html)
URL地址编码
urllib.parse.urlencode({dict})
URL地址中一个查询参数
查询参数:{\’wd\’ : \’美女\’}
urlencode编码后:\’wd=%e7%be%8e%e5%a5%b3\’
from urllib import parse url = \'http://www.baidu.com/s?\' query_string = parse.urlencode({\'wd\':\'美女\'}) print(query_string) # wd=%E7%BE%8E%E5%A5%B3 url = url + query_string # http://www.baidu.com/wd=%E7%BE%8E%E5%A5%B3
URL地址中多个查询参数
from urllib import parse query_string_dict = {\'wd\' : \'美女\', \'pn\' : \'50\'} query_string = parse.urlencode(query_string_dict) url = \'http://www.baidu.com/s?{}\'.format(query_string) print(url) # http://www.baidu.com/s?wd=%E7%BE%8E%E5%A5%B3&pn=50
拼接URL地址的3种方式
1、字符串相加
\’https://www.baidu.com/s?\’ + urlencode({\’wd\’:\’美女\’,\’pn\’:\’50\’})
2、字符串格式化(占位符)
\’https://www.baidu.com/s?%s\’ % urlencode({\’wd\’:\’美女\’,\’pn\’:\’50\’})
3、format()方法
\’https://www.baidu.com/s?{}\’.format(urlencode({\’wd\’:\’美女\’,\’pn\’:\’50\’}))
示例 在百度中输入要搜索的内容,把响应内容保存到本地文件
from urllib import request from urllib import parse # 定义常用变量 word = input(\'请输入搜索内容:\') url = \'http://www.baidu.com/s?\' headers = {\'User-Agent\':\'Mozilla/5.0\'} # url编码,拼接完整URL query_string = parse.urlencode({\'wd\':word}) url = url + query_string # 三步走 req = request.Request(url=url,headers=headers) res = request.urlopen(req) html = res.read().decode(\'utf-8\') filename = \'{}.html\'.format(word) with open(filename,\'w\',encoding=\'utf-8\') as f: f.write(html)
urllib.parse.quote(string)编码
from urllib import parse parse.quote(\'美女\') # %E7%BE%8E%E5%A5%B3
urllib.parse.unquote(string)解码
from urllib import parse result = parse.unquote(\'%E7%BE%8E%E5%A5%B3\') print(result) # 美女
百度贴吧网页获取
- 输入贴吧名称
- 输入起始页
- 输入终止页
- 保存到本地文件:第1页.html、第2页.html …
实现步骤
1、找URL规律
1、不同吧
2、不同页
第1页:http://tieba.baidu.com/f?kw=????&pn=0
第2页:http://tieba.baidu.com/f?kw=????&pn=50
第n页:pn=(n-1)*50
2、获取网页内容
3、保存(本地文件、数据库)
from urllib import request,parse import time import random class BaiduSpider(object): def __init__(self): self.url = \'http://tieba.baidu.com/f?kw={}&pn={}\' self.headers = {\'User-Agent\':\'Mozilla/5.0\'} # 获取响应 def get_page(self,url): req = request.Request(url=url,headers=self.headers) res = request.urlopen(req) html = res.read().decode(\'utf-8\') return html # 保存数据 def write_page(self,filename,html): with open(filename,\'w\') as f: f.write(html) # 主函数 def main(self): name = input(\'请输入贴吧名:\') start = int(input(\'请输入起始页:\')) end = int(input(\'请输入终止页:\')) # 拼接URL地址,发请求 for page in range(start,end+1): pn = (page-1)*50 kw = parse.quote(name) # url编码 url = self.url.format(kw,pn) html = self.get_page(url) # 获取响应,并保存 filename = \'{}-第{}页.html\'.format(name,page) self.write_page(filename,html) print(\'第{}页爬取成功\'.format(page)) # 提示进度 time.sleep(random.randint(1,3)) # 控制爬取速度 if __name__ == \'__main__\': spider = BaiduSpider() spider.main()