Python分布式爬虫前菜(1):关于静态动态网页内容获取的N种方法
来源:互联网 发布:win10软件找不到了 编辑:程序博客网 时间:2024/05/31 13:17
转载自:happengft的博客
http://blog.csdn.net/happengft/article/details/59766342
爬虫是我们快速获取需要的数据的一个非常有效的途径,而爬虫的第一步便是能够请求远方服务器为我们返回所需的网页信息。我们知道,正常情况下在浏览器上我们只要输入正确的统一资源定位器url,即网页地址便可轻松打开我们想要看到页面。同理,在设计python爬虫程序时,我们也可以调用对应的库通过参数设置来连接网络处理http协议。针对静态的网页,常常被使用到的库有urllib, urllib2, requests等等,通过它们可以很方便的请求服务器返回特定地址的网页内容。但是如果遇到JS加载的动态网页,用前面的方法往往收不到我们想要的结果。这时候就可以召唤出强大的自动化测试工具Selenium并喊上它的小伙伴PhantomJS来一起升级打怪了。
(一) urllib, urllib2,直接上例子:
- import urllib2
- response = urllib2.urlopen("http://www.baidu.com")
- print response.read()
上面只要给一个url,例如百度,调用urllib2库便可以单枪匹马读到这个网址对应的网页源码,代码特别简洁。实际爬虫中由于考虑到对方的反爬虫机制,网络响应时间或者发送请求需要添加额外的信息 ,我们需要多添加几行代码,目的是让服务器尽量相信收到的请求都是来自正常的访问对象。为了程序逻辑清晰,我们可以为urlopen设计一个request对象作为传入参数,例如:
- import urllib
- import urllib2
- #添加url
- url = 'xxx'
- request = urllib2.Request(url)
- #为了模拟浏览器行为,伪装对方识别问题,可以添加Headers属性,例如下面的agent便是设置请求身份:
- user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'
- headers = { 'User-Agent' : user_agent}
- request = urllib2.Request(url, headers)
- #有时访问某些网站需要提供一些信息,例如用户名和密码,这时可以这样:
- values = {"username":"yourname","password":"????"}
- data = urllib.urlencode(values)
- request = urllib2.Request(url, data, headers)
- #在遇到网络状况不好时可以设置timeout来设置等待多久超时
- response = urllib2.urlopen(request,timeout=18)
- print response.read()
更多的相关内容可以查看这个urllib和urllib2。
(二)requests,一款简单美观而友好的外部库。
requests所有的功能都可以通过以下7个方法访问。它们全部都会返回一个response对象的实例。
- #创建并发送一个request
- requests.request(method, url, **kwargs)
- 参数:
- method -- method for the new Request object.
- url -- URL for the new Request object.
- params -- (optional) Dictionary or bytes to be sent in the query string for the Request.
- data -- (optional) Dictionary, bytes, or file-like object to send in the body of the Request.
- json -- (optional) json data to send in the body of the Request.
- headers -- (optional) Dictionary of HTTP Headers to send with the Request.
- cookies -- (optional) Dict or CookieJar object to send with the Request.
- files -- (optional) Dictionary of 'name': file-like-objects (or {'name': file-tuple}) for multipart encoding upload. file-tuple can be a 2-tuple ('filename', fileobj), 3-tuple ('filename', fileobj, 'content_type') or a 4-tuple ('filename', fileobj, 'content_type', custom_headers), where 'content-type' is a string defining the content type of the given file and custom_headers a dict-like object containing additional headers to add for the file.
- auth -- (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
- timeout (float or tuple) -- (optional) How long to wait for the server to send data before giving up, as a float, or a (connect timeout, read timeout) tuple.
- allow_redirects (bool) -- (optional) Boolean. Set to True if POST/PUT/DELETE redirect following is allowed.
- proxies -- (optional) Dictionary mapping protocol to the URL of the proxy.
- verify -- (optional) whether the SSL cert will be verified. A CA_BUNDLE path can also be provided. Defaults to True.
- stream -- (optional) if False, the response content will be immediately downloaded.
- cert -- (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
- #例如:
- import requests
- url='xxxx'
- headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'}
- proxies = { 'http' : '127.0.0.1:8118'}
- response=requests.request('GET',url, timeout=20, proxies=proxies, headers=headers)
- 返回类型requests.Response
- 另:
- #发送一个HEAD request.
- requests.head(url, **kwargs)
- #发送一个GET request
- requests.get(url, params=None, **kwargs)
- #发送一个POST request
- requests.post(url, data=None, json=None, **kwargs)
- #发送一个PUT request
- requests.put(url, data=None, **kwargs)
- #发送一个PATCH request
- requests.patch(url, data=None, **kwargs)
- #发送一个DELETE request
- requests.delete(url, **kwargs)
(三)Selenium + PhantomJs,高效处理动态网页的完美组合。
我们使用前面的方法可以单纯的获取网页的html代码,如若是遇到要经过JS渲染的网页内容时则会变得非常麻烦。所以我们需要能够像浏览器一样处理要JS渲染的页面的工具,而PhantomJs正是一款基于WebKit的无界面的网页交互工具,其提供的JavaScript API可以实现自动化浏览、截屏等浏览器功能。Selenium是一款自动化测试工具,其支持Firefox,Chrome,Safari等主流的浏览器,借助selenium就可以模拟人类的各种网页操作行为,例如打开浏览器,输入信息,点击,翻页等等。PhantomJS作为一款无界面的浏览器,Selenium会对它感冒吗?答案是非常感冒,因为PhantomJs不仅能完成浏览器的功能,其效率相对来说还更高。例如:
- from selenium import webdriver
- from selenium.webdriver.common.keys import Keys
- phantomjs_path = '/data/opt/brew/lib/node_modules/phantomjs/lib/phantom/bin/phantomjs'
- driver = webdriver.PhantomJS(executable_path=phantomjs_path)
- url = 'xxxx'
- driver.get(url)
- #轻松得到到JS渲染页面的源码
- page_source = driver.page_source.encode('utf8')
- #定位一个元素的方法有
- find_element_by_id
- find_element_by_name
- find_element_by_xpath
- find_element_by_link_text
- find_element_by_partial_link_text
- find_element_by_tag_name
- find_element_by_class_name
- find_element_by_css_selector
- #定位多元素,返回一个list,方法有
- find_elements_by_name
- find_elements_by_xpath
- find_elements_by_link_text
- find_elements_by_partial_link_text
- find_elements_by_tag_name
- find_elements_by_class_name
- find_elements_by_css_selector
- #例如有如下网页源码:
- <html>
- <body>
- <form id="loginForm">
- <input name="username" type="text" />
- <input name="password" type="password" />
- <input name="continue" type="submit" value="Login" />
- <input name="continue" type="button" value="Clear" />
- </form>
- </body>
- <html>
- #form可以这样来定位
- login_form = driver.find_element_by_id('loginForm')
- #username&password两个元素定位如下
- username = driver.find_element_by_name('username')
- password = driver.find_element_by_name('password')
- #如果使用xpath来定位username,以下方法都ok
- username = driver.find_element_by_xpath("//form[input/@name='username']")
- username = driver.find_element_by_xpath("//form[@id='loginForm']/input[1]")
- username = driver.find_element_by_xpath("//input[@name='username']")
这篇文章简短介绍了网页源码内容获取的各种方法,包括静态网页常常使用到的urllib,urllib2,requests和动态网页使用到的selenium,phantomjs组合。在爬虫过程中,我们往往需要提取并保留网页中有用的信息,所以接下来要介绍的是如何针对获得的网页源码提取出有用信息的工作。
- Python分布式爬虫前菜(1):关于静态动态网页内容获取的N种方法
- Python分布式爬虫前菜(1):关于静态动态网页内容获取的N种方法
- Python分布式爬虫前菜(2):关于提取网页源码中特定信息的技巧
- Python分布式爬虫前菜(2):关于提取网页源码中特定信息的技巧
- c#关于网页内容抓取,简单爬虫的实现。(包括动态,静态的)
- c#关于网页内容抓取,简单爬虫的实现。(包括动态,静态的)
- Python爬虫如何获取动态内容-上
- Python爬虫如何获取动态内容-下
- Python网页静态爬虫
- Python入门简单的静态网页爬虫
- Python爬虫实战(十一):两种简单的方法爬取动态网页
- 分布式下的爬虫Scrapy应该如何做-关于动态内容js或者ajax处理(2)
- 获取网页内容的几种方法
- 网络爬虫获得网页内容的方法
- 关于加快python爬虫获取页面的方法
- 将网页中的静态内容与动态内容在浏览器端分别呈现的方法
- 利用python抓取网页各种类型内容(静态、动态)
- Python网络爬虫(1)获取网页
- C++14:std::bind和std::function
- mongodb, redis, hbase三种nosql数据的对比
- Struts2 类型转换
- java字节数组流操作
- nfs高可用架构之DRBD+heartbeat
- Python分布式爬虫前菜(1):关于静态动态网页内容获取的N种方法
- selenium webdriver + python 环境搭建
- STM32学习笔记:系统的时钟
- java调用外部exe程序并传参
- 计算机模拟——你换不换手
- 解释MySQL外连接、内连接与自连接的区别
- C# VS属性快速封装快捷处理方式
- Struts2 模型驱动
- DSP卷积算法