Python爬虫之Spider类用法简单介绍


Posted in Python onAugust 04, 2020

一、网络爬虫

网络爬虫又被称为网络蜘蛛(?️),我们可以把互联网想象成一个蜘蛛网,每一个网站都是一个节点,我们可以使用一只蜘蛛去各个网页抓取我们想要的资源。举一个最简单的例子,你在百度和谷歌中输入‘Python',会有大量和Python相关的网页被检索出来,百度和谷歌是如何从海量的网页中检索出你想要的资源,他们靠的就是派出大量蜘蛛去网页上爬取,检索关键字,建立索引数据库,经过复杂的排序算法,结果按照搜索关键字相关度的高低展现给你。

千里之行,始于足下,我们从最基础的开始学习如何写一个网络爬虫,实现语言使用Python。

二、Python如何访问互联网

想要写网络爬虫,第一步是访问互联网,Python如何访问互联网呢?

在Python中,我们使用urllib包访问互联网。(在Python3中,对这个模块做了比较大的调整,以前有urllib和urllib2,在3中对这两个模块做了统一合并,称为urllib包。包下面包含了四个模块,urllib.request,urllib.error,urllib.parse,urllib.robotparser),目前主要使用的是urllib.request。

我们首先举一个最简单的例子,如何获取获取网页的源码:

import urllib.request
response = urllib.request.urlopen('https://docs.python.org/3/')
html = response.read()
print(html.decode('utf-8'))

三、Python网络简单使用

首先我们用两个小demo练一下手,一个是使用python代码下载一张图片到本地,另一个是调用有道翻译写一个翻译小软件。

3.1根据图片链接下载图片,代码如下:

import urllib.request

response = urllib.request.urlopen('http://www.3lian.com/e/ViewImg/index.html?url=http://img16.3lian.com/gif2016/w1/3/d/61.jpg')
image = response.read()

with open('123.jpg','wb') as f:
 f.write(image)

其中response是一个对象

输入:response.geturl()
->'http://www.3lian.com/e/ViewImg/index.html?url=http://img16.3lian.com/gif2016/w1/3/d/61.jpg'

输入:response.info()
-><http.client.HTTPMessage object at 0x10591c0b8>

输入:print(response.info())
->Content-Type: text/html
Last-Modified: Mon, 27 Sep 2004 01:23:20 GMT
Accept-Ranges: bytes
ETag: "0f4b59230a4c41:0"
Server: Microsoft-IIS/8.0
Date: Sun, 14 Aug 2016 07:16:01 GMT
Connection: close
Content-Length: 2827

输入:response.getcode()
->200

3.2使用有道词典实现翻译功能

我们想实现翻译功能,我们需要拿到请求链接。首先我们需要进入有道首页,点击翻译,在翻译界面输入要翻译的内容,点击翻译按钮,就会向服务器发起一个请求,我们需要做的就是拿到请求地址和请求参数。

我在此使用谷歌浏览器实现拿到请求地址和请求参数。首先点击右键,点击检查(不同浏览器点击的选项可能不同,同一浏览器的不同版本也可能不同),进入图一所示,从中我们可以拿到请求请求地址和请求参数,在Header中的Form Data中我们可以拿到请求参数。

Python爬虫之Spider类用法简单介绍

(图一)

代码段如下:

import urllib.request
import urllib.parse

url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=dict2.index'
data = {}
data['type'] = 'AUTO'
data['i'] = 'i love you'
data['doctype'] = 'json'
data['xmlVersion'] = '1.8'
data['keyfrom'] = 'fanyi.web'
data['ue'] = 'UTF-8'
data['action'] = 'FY_BY_CLICKBUTTON'
data['typoResult'] = 'true'
data = urllib.parse.urlencode(data).encode('utf-8')
response = urllib.request.urlopen(url,data)
html = response.read().decode('utf-8')
print(html)

上述代码执行如下:

{"type":"EN2ZH_CN","errorCode":0,"elapsedTime":0,"translateResult":[[{"src":"i love you","tgt":"我爱你"}]],"smartResult":{"type":1,"entries":["","我爱你。"]}}

对于上述结果,我们可以看到是一个json串,我们可以对此解析一下,并且对代码进行完善一下:

import urllib.request
import urllib.parse
import json

url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=dict2.index'
data = {}
data['type'] = 'AUTO'
data['i'] = 'i love you'
data['doctype'] = 'json'
data['xmlVersion'] = '1.8'
data['keyfrom'] = 'fanyi.web'
data['ue'] = 'UTF-8'
data['action'] = 'FY_BY_CLICKBUTTON'
data['typoResult'] = 'true'
data = urllib.parse.urlencode(data).encode('utf-8')
response = urllib.request.urlopen(url,data)
html = response.read().decode('utf-8')
target = json.loads(html)
print(target['translateResult'][0][0]['tgt'])

四、规避风险

服务器检测出请求不是来自浏览器,可能会屏蔽掉请求,服务器判断的依据是使用‘User-Agent',我们可以修改改字段的值,来隐藏自己。代码如下:

import urllib.request
import urllib.parse
import json

url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=dict2.index'
data = {}
data['type'] = 'AUTO'
data['i'] = 'i love you'
data['doctype'] = 'json'
data['xmlVersion'] = '1.8'
data['keyfrom'] = 'fanyi.web'
data['ue'] = 'UTF-8'
data['action'] = 'FY_BY_CLICKBUTTON'
data['typoResult'] = 'true'
data = urllib.parse.urlencode(data).encode('utf-8')
req = urllib.request.Request(url, data)
req.add_header('User-Agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36')
response = urllib.request.urlopen(url, data)
html = response.read().decode('utf-8')
target = json.loads(html)
print(target['translateResult'][0][0]['tgt'])

上述做法虽然可以隐藏自己,但是还有很大问题,例如一个网络爬虫下载图片软件,在短时间内大量下载图片,服务器可以可以根据IP访问次数判断是否是正常访问。所有上述做法还有很大的问题。我们可以通过两种做法解决办法,一是使用延迟,例如5秒内访问一次。另一种办法是使用代理。

延迟访问(休眠5秒,缺点是访问效率低下):

import urllib.request
import urllib.parse
import json
import time


while True:
 content = input('please input content(input q exit program):')
 if content == 'q':
  break;

 url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=dict2.index'
 data = {}
 data['type'] = 'AUTO'
 data['i'] = content
 data['doctype'] = 'json'
 data['xmlVersion'] = '1.8'
 data['keyfrom'] = 'fanyi.web'
 data['ue'] = 'UTF-8'
 data['action'] = 'FY_BY_CLICKBUTTON'
 data['typoResult'] = 'true'
 data = urllib.parse.urlencode(data).encode('utf-8')
 req = urllib.request.Request(url, data)
 req.add_header('User-Agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36')
 response = urllib.request.urlopen(url, data)
 html = response.read().decode('utf-8')
 target = json.loads(html)
 print(target['translateResult'][0][0]['tgt'])
 time.sleep(5)

代理访问:让代理访问资源,然后讲访问到的资源返回。服务器看到的是代理的IP地址,不是自己地址,服务器就没有办法对你做限制。

步骤:

1,参数是一个字典{'类型' : '代理IP:端口号' } //类型是http,https等
proxy_support = urllib.request.ProxyHandler({})

2,定制、创建一个opener
opener = urllib.request.build_opener(proxy_support)

3,安装opener(永久安装,一劳永逸)
urllib.request.install_opener(opener)

4,调用opener(调用的时候使用)
opener.open(url)

五、批量下载网络图片

图片下载来源为煎蛋网(http://jandan.net)

图片下载的关键是找到图片的规律,如找到当前页,每一页的图片链接,然后使用循环下载图片。下面是程序代码(待优化,正则表达式匹配,IP代理):

import urllib.request
import os

def url_open(url):
 req = urllib.request.Request(url)
 req.add_header('User-Agent','Mozilla/5.0')
 response = urllib.request.urlopen(req)
 html = response.read()
 return html

def get_page(url):
 html = url_open(url).decode('utf-8')
 a = html.find('current-comment-page') + 23
 b = html.find(']',a)
 return html[a:b]


def find_image(url):
 html = url_open(url).decode('utf-8')
 image_addrs = []
 a = html.find('img src=')
 while a != -1:
  b = html.find('.jpg',a,a + 150)
  if b != -1:
   image_addrs.append(html[a+9:b+4])
  else:
   b = a + 9
  a = html.find('img src=',b)
 for each in image_addrs:
  print(each)
 return image_addrs

def save_image(folder,image_addrs):
 for each in image_addrs:
  filename = each.split('/')[-1]
  with open(filename,'wb') as f:
   img = url_open(each)
   f.write(img)

def download_girls(folder = 'girlimage',pages = 20):
 os.mkdir(folder)
 os.chdir(folder)
 url = 'http://jandan.net/ooxx/'
 page_num = int(get_page(url))

 for i in range(pages):
  page_num -= i
  page_url = url + 'page-' + str(page_num) + '#comments'
  image_addrs = find_image(page_url)
  save_image(folder,image_addrs)

if __name__ == '__main__':
 download_girls()

代码运行效果如下:

Python爬虫之Spider类用法简单介绍

到此这篇关于Python爬虫之Spider类用法简单介绍的文章就介绍到这了,更多相关Python爬虫Spider类内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python3使用tkinter实现ui界面简单实例
Jan 10 Python
Python编程语言的35个与众不同之处(语言特征和使用技巧)
Jul 07 Python
浅谈python 四种数值类型(int,long,float,complex)
Jun 08 Python
python3实现ftp服务功能(服务端 For Linux)
Mar 24 Python
Python自动化运维之IP地址处理模块详解
Dec 10 Python
基于python内置函数与匿名函数详解
Jan 09 Python
基于循环神经网络(RNN)的古诗生成器
Mar 26 Python
解决matplotlib库show()方法不显示图片的问题
May 24 Python
python字符串中匹配数字的正则表达式
Jul 03 Python
详解python命令提示符窗口下如何运行python脚本
Sep 11 Python
Scrapy实现模拟登录的示例代码
Feb 21 Python
分享几种python 变量合并方法
Mar 20 Python
Python绘图之二维图与三维图详解
Aug 04 #Python
Python连接Impala实现步骤解析
Aug 04 #Python
python利用蒙版抠图(使用PIL.Image和cv2)输出透明背景图
Aug 04 #Python
Python如何给函数库增加日志功能
Aug 04 #Python
pycharm导入源码的具体步骤
Aug 04 #Python
python根据用户需求输入想爬取的内容及页数爬取图片方法详解
Aug 03 #Python
Python 如何调试程序崩溃错误
Aug 03 #Python
You might like
php中动态变量用法实例
2015/06/10 PHP
PHP模糊查询技术实例分析【附源码下载】
2019/03/07 PHP
JavaScript入门之基本函数详解
2011/10/21 Javascript
修改jQuery Validation里默认的验证方法
2012/02/14 Javascript
JavaScript对象和字串之间的转换实例探讨
2013/04/21 Javascript
js实现兼容性好的微软官网导航下拉菜单效果
2015/09/07 Javascript
基于jQuery Ajax实现上传文件
2016/03/24 Javascript
AngularJS应用开发思维之依赖注入3
2016/08/19 Javascript
AngularJs基于角色的前端访问控制的实现
2016/11/07 Javascript
使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能
2018/03/22 Javascript
vue实现验证码按钮倒计时功能
2018/04/10 Javascript
JavaScript面向对象继承原理与实现方法分析
2018/08/09 Javascript
layui 优化button按钮和弹出框的方法
2018/08/15 Javascript
详解nodejs解压版安装和配置(带有搭建前端项目脚手架)
2018/12/06 NodeJs
js实现通过开始结束控制的计时器
2019/02/25 Javascript
微信小程序 wepy框架与iview-weapp的用法详解
2019/04/10 Javascript
微信小程序入口场景的问题集合与相关解决方法
2019/06/26 Javascript
layui在form表单页面通过Validform加入简单验证的方法
2019/09/06 Javascript
jQuery实现颜色打字机的完整代码
2020/03/19 jQuery
Python爬虫包BeautifulSoup实例(三)
2018/06/17 Python
Python实现的网页截图功能【PyQt4与selenium组件】
2018/07/12 Python
pycharm远程linux开发和调试代码的方法
2018/07/17 Python
Python后台管理员管理前台会员信息的讲解
2019/01/28 Python
举例讲解Python常用模块
2019/03/08 Python
python如何快速拼接字符串
2020/10/28 Python
Python远程linux执行命令实现
2020/11/11 Python
HTML5地理定位与第三方工具百度地图的应用
2016/11/17 HTML / CSS
世界上最大的售后摩托车零配件超市:J&P Cycles
2017/12/08 全球购物
世界上最大的冷却器制造商:Igloo Coolers
2019/07/23 全球购物
Linux上比较文件的命令都有哪些
2012/02/24 面试题
客房主管岗位职责
2013/12/09 职场文书
幼儿园标语大全
2014/06/19 职场文书
小学运动会入场口号
2015/12/24 职场文书
导游词之藏龙百瀑景区
2019/12/30 职场文书
深入浅出讲解Java8函数式编程
2022/01/18 Java/Android
Vue3中toRef与toRefs的区别
2022/03/24 Vue.js