urllib爬虫(流程+案例)

目录 1、urllib爬取网页 2、爬取到的网页直接写入文件 3、模拟浏览器 4、设置超时 5、http请求 6、json数据解析 7、抓取网页动态Ajax请求的数据 8、糗事百科爬虫   网络爬虫是一种按照一定规则自动抓取万维网信息的程序。在如今网络发展,信息爆炸的时代,信息的处理变得尤为重要。而这之前就需要获取到数据。有关爬虫的概念可以到网上查看详细的说明,今天在这里介绍一下使用urllib进行网络爬虫的方法使用,在最后的一个案例中把最基本的爬虫要素运用进去,可以作为初学者的一个模板,读懂它进行适当修改就可以使用。   以我的经验来看,在编程上对于陌生的简单的东西,最快的学习方法就是从代码入手了。当然有些很厉害的兄弟,可以完全忽略我这篇博客了。下面的内容我尽量将注释写在代码当中。 回到顶部 1、urllib爬取网页   下面是通过urllib的request函数来获取网页信息,现在的request库也很方便,不过原理都是一样的。 复制代码 1 import urllib.request 2 3 # 向指定的url地址发送请求并返回服务器响应的数据(文件的对象) 4 response = urllib.request.urlopen("http://www.baidu.com") 5 6 # 读取文件的全部内容,会把读到的东西赋值给一个字符串变量 7 data = response.read() 8 print(data) # 读取得到的数据 9 print(type(data)) # 查看数据类型 10 11 # 读取一行 12 data = response.readline() 13 14 # 读取文件的全部内容,赋值给一个列表变量,优先选择 15 data = response.readlines() 16 # print(data) 17 print(type(data[100])) 18 print(type(data[100].decode("utf-8"))) # 转字符串 19 print(len(data)) 20 21 # 将爬取到的网页写入文件 22 with open(r"F:/python_note/爬虫/file/file1.html", "wb") as f: 23 f.write(data) 24 25 26 # response 属性 27 28 # 返回当前环境的有关信息 29 print(response.info()) 30 31 # 返回状态码 32 print(response.getcode()) 33 # 200为正常,304位为有缓存 34 35 # 返回当前正在爬取的url地址 36 print(response.geturl()) 37 38 url = "https://www.sogou.com/sgo?query=凯哥学堂&hdq=sogou-wsse-16bda725ae44af3b-0099&lxod=0_16_1_-1_0&lxea=2-1-D-9.0.0.2502-3-CN1307-0-0-2-E96F3D19F4C66A477CE71FD168DD223D-62&lxoq=kaigexuetang&lkx=0&ie=utf8" 39 url2 = r"https%3A//www.sogou.com/sgo%3Fquery%3D%E5%87%AF%E5%93%A5%E5%AD%A6%E5%A0%82%26hdq%3Dsogou-wsse-16bda725ae44af3b-0099%26lxod%3D0_16_1_-1_0%26lxea%3D2-1-D-9.0.0.2502-3-CN1307-0-0-2-E96F3D19F4C66A477CE71FD168DD223D-62%26lxoq%3Dkaigexuetang%26lkx%3D0%26ie%3Dutf8" 40 41 newurl = urllib.request.quote(url) # 将含汉字的编码 42 print(newurl) 43 newurl2 = urllib.request.unquote(url2) # 解码 44 print(newurl2) 45 46 47 # 端口号,http 80 48 # https 443 复制代码 回到顶部 2、爬取到的网页直接写入文件   将网页信息写入文件可以通过上面的读取然后再写入文件,还有更简便的方法,就是爬取页面的同时写入文件,这个也不难,只是一个函数而已。相信应该可以明白下面的内容,filename后面的内容就是需要存储网页信息的文件路径。 复制代码 1 import urllib.request 2 3 urllib.request.urlretrieve("http://www.baidu.com", 4 filename=r"F:/python_note/爬虫/file/file2.html") 5 6 # urlretrieve在执行过程中,会产生一些缓存 7 # 清除缓存 8 urllib.request.urlcleanup() 复制代码 回到顶部 3、模拟浏览器   我们都知道,进行爬虫的时候,很在乎它的效率,计算机进行获取数据当然会比手动来的快。但是这样一来,你就占用了该网站的大部分带宽,导致其他人上网会很卡。因此,很多网站会有自己的反爬机制,有些只是简单的预防一下。通过网络爬虫进行访问时会有一个爬虫的请求头,那么,可以模拟一下浏览器来访问,也就是把请求头中的信息换成浏览器信息。网上可以找到很多,随便粘贴一个就好了。 复制代码 1 import random 2 import urllib.request 3 4 url = "http://www.baidu.com" 5 6 ''' 7 # 模拟请求头 (这是一种方法,下面使用另一种方法) 8 headers = { 9 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3493.3 Safari/537.36" 10 } 11 # 设置一个请求体 12 req = urllib.request.Request(url, headers=headers) 13 # 发起请求 14 response = urllib.request.urlopen(req) 15 data = response.read() 16 print(data) 17 ''' 18 19 agentsList = [ 20 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60", 21 "Opera/8.0 (Windows NT 5.1; U; en)", 22 "Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50", 23 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50", 24 "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0 " 25 ] 26 27 agentStr = random.choice(agentsList) # 这里是从列表中随机取出一个浏览器信息来改写请求头,避免被网站发现同一个地址快速持续的访问它而被封掉 28 req = urllib.request.Request(url) # 里面添加头要写成键值对 29 # 向请求体里添加了User-Agent 30 req.add_header("User-Agent", agentStr) # 这里添加时传入两个字符串,自动组合 31 32 response = urllib.request.urlopen(req) 33 print(response.read()) 复制代码 回到顶部 4、设置超时   当访问一直没有被响应时,我们需要让它继续往下进行而不是卡在那里。通过异常捕获来实现。 复制代码 1 import urllib.request 2 3 # 如果网页长时间未响应,系统判断超时,无法爬取 4 for i in range(1, 100): 5 try: 6 response = urllib.request.urlopen("http://www.baidu.com", timeout=0.1) 7 print(len(response.read())) 8 except: 9 print("time out") 复制代码 回到顶部 5、http请求   当然有些网站还需要先登录之类的,也就是不仅仅从上面获取信息,还需要上传一些东西,下面介绍一下发送请求的两种方法。 复制代码 1 ''' 2 使用场景:进行客户端与服务端之间的消息传递时使用 3 GET: 通过url网址传递信息,可以直接在url网址上添加要传递的信息(不安全) 4 POST: 可以向服务器提交数据,是一种比较流行,安全的数据传递方式 5 PUT: 请求服务器存储一个资源,通常要指定存储的位置 6 DELETE: 请求服务器删除一个资源 7 HEAD: 请求获取对应的http报头信息 8 OPTIONS: 可以获取当前url所支持的请求类型 9 ''' 10 11 ''' 12 get请求: 13 特点:把数据拼接到请求路径后面传递给服务器 14 优点:速度快 15 缺点:承载的数据量小,不安全 16 ''' 17 18 ''' 19 post请求: 20 特点:把参数进行打包,单独传输 21 优点:数量大,安全(当对服务器数据进行修改时建议使用post) 22 缺点:速度慢 23 ''' 24 import urllib.request 25 import urllib.parse # 对请求打包的库 26 27 url = "http://www.baidu.com" 28 # 将要发送的数据合成一个字典 29 # 字典的键去网址里找,一般为input标签的name属性的值 30 data = { 31 "username": "xiaoxiao", 32 "passwd": "999" 33 } 34 # 对要发送的数据进行打包 35 postdata = urllib.parse.urlencode(data).encode("utf-8") 36 37 # 请求体 38 req = urllib.request.Request(url, data=postdata) 39 40 # 请求 41 response = urllib.request.urlopen(req) 42 print(response.data()) 复制代码 回到顶部 6、json数据解析 复制代码 1 ''' 2 概念:一种保存数据的格式 3 作用:可以保存本地的json文件,也可以将json串进行传输,通常将json称为轻量级的传输方式 4 xml可读性更强,但是有很多没有用的标签 5 json文件组成: 6 {} 代表对象(字典) 7 [] 代表列表 8 : 代表键值对 9 , 分隔两个部分 10 ''' 11 12 import json 13 14 # 将json格式的字符串转换为Python数据类型的对象 15 16 jsonStr = '{"name":"xiaoxiao", "age":18, "hobby":["money", "power", "english"], "parames":{"a":1, "b":2}}' 17 18 jsonData = json.loads(jsonStr) 19 print(jsonData) 20 print(type(jsonData)) 21 print(jsonData["hobby"]) 22 23 24 jsonData2 = {"name": "xiaoxiao", "age": 18, "hobby": [ 25 "money", "power", "english"], "parames": {"a": 1, "b": 2}} 26 # python类型的数据就是比json格式少个引号 27 28 # 将Python数据类型的对象转换为json格式的字符串 29 30 jsonStr2 = json.dumps(jsonData2) 31 print(jsonStr2) 32 print(type(jsonStr2)) 复制代码 回到顶部 7、抓取网页动态Ajax请求的数据   经常浏览一些网页会有这种情况,就是首先加载出一个页面的内容,向下滚动还有内容,在最下面会有一个提示下拉获取更多内容这类的东西。这个可以让加载网页的速度更快,毕竟内容少了嘛,再我们想要看到更多信息时候再加载。对于这样的一部分页面爬取其实也很简单,细心观察一下每次多加载一块的页面时,这时候上方的网址变化可以发现,有些是有数字变化的。可以根据里面的具体规律来修改每次请求的信息。 复制代码 1 import urllib.request 2 import ssl 3 import json 4 5 6 def ajaxCrawler(url): 7 headers = { 8 "User-Agent": "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10" 9 } 10 req = urllib.request.Request(url, headers=headers) 11 12 # 使用ssl创建未验证的上下文 13 context = ssl._create_unverified_context() # 访问的是HTTPS 14 15 response = urllib.request.urlopen(req, context=context) 16 jsonStr = response.read().decode("utf-8") 17 print(type(response.read())) # byte型 18 print(type(response.read().decode("utf-8"))) # json字符串型 19 jsonData = json.loads(jsonStr) 20 return jsonData 21 22 23 # url = "https://movie.douban.com/j/chart/top_list?type=17&interval_id=100%3A90&action=&start=0&limit=20" 24 # info = ajaxCrawler(url) 25 # print(info) 26 27 for i in range(1, 11): 28 url = "https://movie.douban.com/j/chart/top_list?type=17&interval_id=100%3A90&action=&start=" + \ 29 str(i * 20) + "&limit=20" 30 info = ajaxCrawler(url) 31 print(len(info)) 复制代码 回到顶部 8、糗事百科爬虫 复制代码 1 import urllib.request 2 import re 3 4 # https://www.qiushibaike.com/text/page/2/ 5 6 7 def jokeCrawler(url): 8 headers = { 9 "User-Agent": "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10" 10 } 11 req = urllib.request.Request(url, headers=headers) 12 response = urllib.request.urlopen(req) 13 14 html = response.read().decode("utf-8") 15 # print(type(html)) 16 17 pat = r'
(.*?)' 18 re_joke = re.compile(pat, re.S) # re.S 使可以匹配换行 19 divsList = re_joke.findall(html) 20 # print(divsList) 21 # print(len(divsList)) 22 23 dic = {} 24 for div in divsList: 25 # 用户名 26 re_u = re.compile(r"

(.*?)

", re.S) 27 username = re_u.findall(div) 28 username = username[0].rstrip() 29 # print(username) 30 # 段子 31 re_d = re.compile(r'
\n(.*?)', re.S) 32 duanzi = re_d.findall(div) 33 duanzi = duanzi[0].strip() 34 # print(type(duanzi)) 35 dic[username] = duanzi 36 return dic 37 38 # with open(r"F:/python_note/爬虫/file/file2.html", "w") as f: 39 # f.write(html) 40 41 42 url = "https://www.qiushibaike.com/text/page/1/" 43 info = jokeCrawler(url) 44 for k, v in info.items(): 45 print(k + ':\n' + v) 复制代码 作者:渔单渠 出处:https://www.cnblogs.com/yudanqu/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.https://www.cnblogs.com/yudanqu/p/9733502.html
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信