爬虫
HWY
2018-05-19
基本模块 POST请求的处理 动态网页的抓取 下载图片 json数据处理 urllib.request code: import urllib.request # 通过urlopen这个方法向指定的url发送请求,并放回服务器响应的数据 response = urllib.request.urlopen("http://www.huangwenyang.cn/") # 通过read读取返回的全部数据,并通过decode指定编码方式,赋值给一个字符变量 # data = response.read().decode("utf-8") # 每次读取一行内容,可以通过循环来读取数据 data1 = response.readline().decode("utf-8") # 读取全部数据,但是赋值给一个列表变量,每一行为一个元素 data2 = response.readlines() print(data2[100].decode("utf-8")) response 属性 response.info() response.getcode() response.geturl() urllib.request.unquote(url) 返回当前环境的相关信息 code: print(response.info()) result: Date: Tue, 15 May 2018 08:42:11 GMT Server: WSGIServer/0.1 Python/2.7.12 Vary: Cookie X-Frame-Options: SAMEORIGIN Content-Type: text/html; charset=utf-8 Content-Length: 12492 返回状态码 200代表访问正常 304代表有缓存 返回当前请求的url 对指定的url进行解码 urllib.request.quote(url) 对指定的url进行编码,只能通过编码后的url 来爬取 json就是一种存储和传输信息的一种语法,类似于xml,其优点是存储量小,但是可读性不高 一般从网页获得的json数据是一个格式类似于字典但是类型是字符串的数据,对json数据进行 处理之前一般先把数据转化为字典,再来进行处理 将json数据类型转化为Python中的字典数据类型 code: import urllib.request import json url = r'http://127.0.0.1:8000/index/' response = urllib.request.urlopen(url) data = response.read().decode("utf-8") print(data) print(type(data)) # 将json格式的数据转化为Python数据类型 jsondata = json.loads(data) print(jsondata["name"]) print(type(jsondata)) 可以看到从本地服务器获取下来的数据类型为一个字符串,但是这样来对数据进行 处理是比较麻烦的,所以通过json.loads(data) 将字符串数据转换为了字典,这样 对数据进行处理就方便了很多 result: {"name": "hwy", "age": "20"} <class 'str'> hwy <class 'dict'> 将Python的字典数据转化为json数据类型 code: from django.shortcuts import HttpResponse import json # Create your views here. def index(request): data = {"name": "hwy", "age": "20"} jsondata = json.dumps(data) return HttpResponse(jsondata) 上面就是我在本地服务器上面通过字典构造的json数据 首先我写了一个字典,再通过json.dumps(data) 将字典转化为了json数据, 再通过服务器传输出去 将Python字典数据以json数据类型存储到本地 一种方法是先将数据进行转化,咋u存入本地 但是也可以直接在存储时进行数据类型的处理 code: import json # 将Python数据转化为json数据类型 data = {"name": "hwy", "age": "20"} jsondata = json.dumps(data) print(jsondata) print(type(jsondata)) # 将data这个字典以json数据类型写入本地 path = r"C:\Users\Administrator\Desktop\hwy.json" # with open(path, "w") as f: # json.dump(data, f) # 读取本地的json数据 with open(path, "r") as f: r = f.read() print(r) print("--------") print(type(r)) newr = json.loads(r) print(newr) print(type(newr)) 将本地json数据读取出来 code: import json # 将Python数据转化为json数据类型 data = {"name": "hwy", "age": "20"} jsondata = json.dumps(data) print(jsondata) print(type(jsondata)) # 将data这个字典以json数据类型写入本地 path = r"C:\Users\Administrator\Desktop\hwy.json" # with open(path, "w") as f: # json.dump(data, f) # 读取本地的json数据 with open(path, "r") as f: r = f.read() print(r) print("--------") print(type(r)) newr = json.loads(r) print(newr) print(type(newr)) post请求是一种传输数据的方式,区别于get在于其传输的数据量可以很大,且传输安全,但是由于需要先将数据进行打包,所以 传输的效率较低 POST请求通常用于登录等数据要求安全的场合 get请求传输数据的方式是将数据直接追加在url之后,所以传输数据量小且不安全 POST请求一般需要向目标url提交表单,所以用爬虫进行访问时也需要手动创建一个表单 code: import urllib.request import urllib.parse url = "http://127.0.0.1:8000/form/" # 创建请求所需的数据 re_data = { "username": "hwy", "passwd": "123", } # 将数据进行打包,并指定编码格式 post_data = urllib.parse.urlencode(re_data).encode("utf-8") # 构造请求体 req = urllib.request.Request(url, post_data) # 请求 response = urllib.request.urlopen(req) data = response.read().decode("utf-8") print(data) 构造的数据里面的key值要与from表单中的name值相对应 所谓的动态网页就是通过ajax使每次返回给客户端一定数量的数据,当需要更多数据的时候,可以不重新加载网页而获得其余数据的一类网页 对于这类网站,通常是当你要加载更多数据时通过get请求向服务器放松数据,一般是发送 start 和 limit 来说明从哪里开始,加载的数据是多少 url : https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action=&start=0&limit=20 这就是豆瓣的动态加载的url 所以加载动态网页的思路就是通过改变 start 和 limit的值来不断的加载更多的数据 import urllib.request import json import ssl def spider(url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:59.0) Gecko/20100101 Firefox/59.0" } # 创建请求体 req = urllib.request.Request(url, headers=headers) # 使用ssl创建不验证的上下文,从而可以爬取https安全网站 context = ssl._create_unverified_context() # 发起请求 reponse = urllib.request.urlopen(req, context=context) data = reponse.read().decode("utf-8") data = json.loads(data) return data # url = "https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action=&start=0&limit=1" # result = spider(url) # print(result) # print(len(result)) j = 1 for i in range(0, 10): url = "https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action=&start=" + str(i * 20) + "&limit=20" result = spider(url) for info in result: with open(r"C:\Users\Administrator\Desktop\dou.txt", "a", encoding="utf-8") as f: f.write(str(j) + info["title"] + "\n") j = j + 1 print(len(result)) code: import urllib.request import re import os def spider(url): # 创建请求头,模拟浏览器请求 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:59.0) Gecko/20100101 Firefox/59.0" } # 利用请求头来创建请求体 req = urllib.request.Request(url, headers=headers) # 发起请求 response = urllib.request.urlopen(req) # 获得放回的数据并指定解码格式 data = response.read().decode('UTF-8') return data url = r"http://www.tgirl.cc/gctt/kimoe" result = spider(url) # 正则字符串 re_str1 = r'<span class="read-more"><a href="([\s\S]*?)">阅读全文»</a></span>' re_str2 = r'<div id="post_content">([\s\S]*?)<div class="xydown_down_link">' re_str3 = r'<img src="([\s\S]*?)" alt="' img_url_list1 = re.findall(re_str1, result) num = 1 # 图片存储的路径 path = r"C:\Users\Administrator\Desktop\img" # 打开对应的总览的链接 for img_url_l in img_url_list1: # 打开总览后返回的数据 download_html = spider(img_url_l) download_url = re.findall(re_str2, download_html) img_url_list2 = re.findall(re_str3, download_url[0]) # print(download_url) # 下载图片到本地 for img in img_url_list2: filename = os.path.join(path, str(num) + ".jpg") urllib.request.urlretrieve(img, filename=filename) print(img) num += 1 spider