Get方式
GET请求一般用于我们向服务器获取数据,比如说,我们用百度搜索传智播客
:https://www.baidu.com/s?wd=传智播客
浏览器的url会跳转成如图所示:
https://www.baidu.com/s?wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2
在其中我们可以看到在请求部分里,http://www.baidu.com/s?
之后出现一个长长的字符串,其中就包含我们要查询的关键词传智播客,于是我们可以尝试用默认的Get方式来发送请求。
from urllib import request, parse # parse负责url编码处理 url = "http://www.baidu.com/s" word = {"wd":"传智播客"} word = parse.urlencode(word) #转换成url编码格式(字符串) newurl = url + "?" + word # url首个分隔符就是 ? headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"} req = request.Request(newurl, headers=headers) response = request.urlopen(req) print(response.read())
批量爬取贴吧页面数据
首先我们创建一个python文件, tiebaSpider.py,我们要完成的是,输入一个百度贴吧的地址,比如:
百度贴吧LOL吧第一页:http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=0
第二页: http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=50
第三页: http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=100
发现规律了吧,贴吧中每个页面不同之处,就是url最后的pn的值,其余的都是一样的,我们可以抓住这个规律。
简单写一个小爬虫程序,来爬取百度LOL吧的所有网页。
- 先写一个main,提示用户输入要爬取的贴吧名,并用 urllib.parse.urlencode()进行转码,然后组合url,假设是lol吧,那么组合后的url就是:
http://tieba.baidu.com/f?kw=lol
# 模拟 main 函数 if __name__ == "__main__": kw = input("请输入需要爬取的贴吧:") # 输入起始页和终止页,str转成int类型 beginPage = int(input("请输入起始页:")) endPage = int(input("请输入终止页:")) url = "http://tieba.baidu.com/f?" key = urllib.parse.urlencode({"kw" : kw}) # 组合后的url示例:http://tieba.baidu.com/f?kw=lol url = url + key tiebaSpider(url, beginPage, endPage)
- 接下来,我们写一个百度贴吧爬虫接口,我们需要传递3个参数给这个接口, 一个是main里组合的url地址,以及起始页码和终止页码,表示要爬取页码的范围。
def tiebaSpider(url, beginPage, endPage): """ 作用:负责处理url,分配每个url去发送请求 url:需要处理的第一个url beginPage: 爬虫执行的起始页面 endPage: 爬虫执行的截止页面 """ for page in range(beginPage, endPage + 1): pn = (page - 1) * 50 filename = "第" + str(page) + "页.html" # 组合为完整的 url,并且pn值每次增加50 fullurl = url + "&pn=" + str(pn) #print(fullurl) # 调用loadPage()发送请求获取HTML页面 html = loadPage(fullurl, filename) # 将获取到的HTML页面写入本地磁盘文件 writeFile(html, filename)
- 我们已经之前写出一个爬取一个网页的代码。现在,我们可以将它封装成一个小函数loadPage,供我们使用。
def loadPage(url, filename): ''' 作用:根据url发送请求,获取服务器响应文件 url:需要爬取的url地址 filename: 文件名 ''' print("正在下载" + filename) headers = {"User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"} req = urllibrequest.Request(url, headers = headers) response = request.urlopen(req) return response.read()
- 最后如果我们希望将爬取到了每页的信息存储在本地磁盘上,我们可以简单写一个存储文件的接口。
def writeFile(html, filename): """ 作用:保存服务器响应文件到本地磁盘文件里 html: 服务器响应文件 filename: 本地磁盘文件名 """ print "正在存储" + filename with open(filename, 'w', encoding='utf-8') as f: f.write(html) print "-" * 20
完整代码:
from urllib import request, parse import sys def loadPage(url, filename): """ 作用: 根据url发送请求, 获取服务器相应文件 url: 需要爬取的url地址 """ print("正在下载" + filename) headers = { "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 = request.Request(url, headers=headers) # 获得系统的编码 type = sys.getfilesystemencoding() # 设置爬出内容的编码 print(type) # ************************************************ html = request.urlopen(req).read().decode(type) # ************************************************ print(html) return html def writePage(html, filename): """ 作用: 将html内容写入到本地 html: 服务器相应文件内容 """ print("正在保存" + filename) # *********************************************** with open(filename, "w", encoding="utf-8") as f: # *********************************************** f.write(html) print("*" * 30) def tiebaSpider(url, bingenPage, endPage): """ 作用: 爬虫爬虫调度器, 负责组合处理每一个页面的url url: 贴吧url的前部分, beginPage: 起始页 endPage: 终止页 """ for page in range(beginPage, endPage + 1): pn = (page - 1) * 50 filename = " 第" + str(page) + "页.html" fullurl = url + "&pn=" + str(pn) print(fullurl) html = loadPage(fullurl, filename) writePage(html, filename) if __name__ == "__main__": kw = input("请输入需要爬取的贴吧名:") beginPage = int(input("请输入起始页编号")) endPage = int(input("请输入结束页编号:")) url = "http://tieba.baidu.com/f?" key = parse.urlencode({"kw": kw}) fullurl = url + key tiebaSpider(fullurl, beginPage, endPage)
其实很多网站都是这样的,同类网站下的html页面编号,分别对应网址后的网页序号,只要发现规律就可以批量爬取页面了。