mac 终端安装 beautifulbs4 soup.select4提示can't read /var/mail/bs4怎么解决

Python高级爬虫(四):动态加载页面的解决方案与爬虫代理 | 邪恶十六进制
& Python高级爬虫(四):动态加载页面的解决方案与爬虫代理
*原创作者:VillanCh
0×00 前言
0×01 动态页面解决方案Selenium+PhantomJS
0×02 原理回顾对比
0×03 Quick Start
0×04 webdriver API
0×05 匿名爬虫
0×06 匿名爬虫解决方案
0×07 完结总结
0×00 前言
如果读者读过我前面的关于爬虫的文章,应该大概都清楚我们现在可以对一个静态的web页面”为所欲为“了,但是技术的发展总是没有止境的,仅仅是这样对静态页面处理远远不够,要知道现在很多的web页面有意无意为了防止静态爬虫使用ajax技术动态加载页面,这就导致了在面对这些网站的时候,我们前面的技术并不能起到什么很好的效果,所以,我在本系列文章开头就说了会提供动态加载网页的解决方案,在这篇文章里,笔者就在这里提出这个解决方案,用来解决以前我们没有办法的问题。
0×01 动态页面解决方案Selenium+PhantomJS
Python2(或Python3)&&&&& 本文使用Python2.7.11
Selenium&&&&&&&&&&&&&&&&&&&&&&&&&&& 自动化web测试解决方案
PhantomJS&&&&&&&&&&&&&&&&&&&&&&&& 一个没有图形界面的浏览器
0×02 原理回顾对比
讨论:讲selenium自动化测试技术应用于爬虫数据挖掘,其实我也是经历了一段时间的思考,有一些基础的朋友们可能会知道,BeautifulSoup这种完全基于静态的web页面分析是没有办法执行JS的,但是我们在使用web的过程中,基本不可能不用到JS脚本,当时我就想寻找一个JS引擎整合BeautifulSoup,然后计划使用Spidermonkey这个技术,如果需要这么做的话,我们会发现,我们不仅要用BeautifulSoup爬取页面的目标元素,而且还要考虑爬取JS脚本,在执行这些js脚本后,我们还需要再次分析这些脚本返回的数据或者是对HTML页面产生的影响,我觉得这样加大了太多的不确定因素,我们不想花太多的时间放在脚本编写上,既然选用Python,就要发挥它的巨大Pythonic的优势。然后还有一个解决方案就是。我想也许我们通过这个方案介绍的不仅仅是爬虫,也可能是一个新世界的大门,所以我还是选择selenium吧,web自动化测试的一整套解决方案。
其实我们从BeautifulSoup的解决方案过度到selenium的方案就是一个思维上的“退步“的过程,从直接HTML解析-&分析JS-&webkit-&索性直接用headless浏览器来操作web页面的selenium。
所以也就是说,我们接下来要讨论的selenium用于爬虫和以前学习的静态页面处理有着本质的区别,可以认为对我们来说是一个全新的技术。
0×03 Quick Start
在这里我们首先可以很负责任的说,通过以下的例子并不会让读者完全掌握selenium的使用,但是通过动手,大家可以了解到selenium是非常好用并且并不输于BeautifulSoup的(也许这两个并不是一个级别并不能比较)。但是可以说BeautifulSoup中的定位元素,在selenium中都可以做到,而且Selenium可以设置等待时间让页面完成加载,或者设置条件让web页面加载出我们所需要的数据然后再获取数据。
下载与安装:
首先我们需要下载要给PhantomJS浏览器from。
然后安装selenium,使用easy_install或者pip都可以很方便的安装:
1.easy_install selenium
2.pip install selenium
然后我们的第一个目标页面很简单,就是一个存在ajax的情况:页面如下:
&title&Some JavaScript-loaded content&/title&
&script src="../js/jquery-2.1.1.min.js"&&/script&
&div id="content"&
This is some content that will appear on the page while it's loading. You don't care about scraping this.
& & type: "GET",
& & url: "loadedContent.php",
& & success: function(response){
& & & & setTimeout(function() {
& & & & & & $('#content').html(response);
& & & & }, 2000);
function ajax_delay(str){
&setTimeout("str",2000);
我们简单看到这个web页面是使用ajax动态加载数据,GET请求LoadedContent.php然后把结果直接显示在content里。对于这样的方式我们并不需要太深入了解,总之我们只需要知道我们如果使用传统的方式获取,得到的就是上面的静态html而没有loadedContent.php中的内容。
作为selenium的爬虫应用quickstart,我们没必要太深入讲解原理,我们需要把PhantomJS和python脚本放在同一个文件夹下,建立selenium_test.py文件夹
然后输入selenium_test.py中的内容:
#引入selenium中的webdriver
from selenium import webdriver
import time
#webdriver中的PhantomJS方法可以打开一个我们下载的静默浏览器。
#输入executable_path为当前文件夹下的phantomjs.exe以启动浏览器
driver =webdriver.PhantomJS(executable_path="phantomjs.exe")
#使用浏览器请求页面
driver.get("/pages/javascript/ajaxDemo.html")
#加载3秒,等待所有数据加载完毕
time.sleep(3)
#通过id来定位元素,
#.text获取元素的文本数据
print driver.find_element_by_id('content').text
#关闭浏览器
driver.close()
建议大家先用传统的方法尝试一下这个页面,再使用上面的脚本来执行。观察两个结果有什么不同。当然,我这里明确说明:如果大家真的不想再学习selenium的定位元素,发送数据等操作了,其实也是没什么问题的。通过一个叫page_source的属性,我们完全可以获取当前整个页面的和html,然后再把页面传给BeautifulSoup,这样我们仍然可以使用BeautifulSoup进行解析。&
0×04 Webdriver API
我们发现要使用selenium分析页面,导入的是webdriver,webdriver有很多易用的API:
定位元素,控制浏览器行为,刷新,web元素操作,模拟键盘鼠标事件,获得验证信息,设置等待时间,上传下载文件,调用javascript,窗口截图。
我们写简单的爬虫可能要用得到的就是元素定位和设置等待时间,笔者在这里利用这两个特性再写一个例子供大家理解:
爬取淘宝的商品信息
我们爬取一个淘宝的页面,其实静态很难爬取,淘宝的反爬虫措施相当到位,我们可以先用最简单的方式尝试一下:
import bs4
import requests
r = requests.get("/search?q=surface&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.2-taobao-item.1&ie=utf8&initiative_id=tbindexz_")
data = r.content
soup = bs4.BeautifulSoup(data)
for tag in soup.tagStack:
print tag.encode('gbk','ignore')
我们发现结果:
同时我们发现,通过这种方式获得的html中是没有商品信息的。这样基本所有的静态方式都不可以使用了。
但是selenium的办法是直接操作浏览器所以淘宝并不能挡得住这种数据搜集。
我们先简单看一下能否获取到这个淘宝页面:
from selenium import webdriver
import time
driver = webdriver.PhantomJS(executable_path="phantomjs.exe")
driver.get("/search?q=surface&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.2-taobao-item.1&ie=utf8&initiative_id=tbindexz_")
time.sleep(7)
print driver.page_source.encode('gbk','ignore') #这个函数获取页面的html
driver.get_screenshot_as_file("2.jpg") #获取页面截图
print "Success To Create the screenshot & gather html"
driver.close()
我们还是轻松加愉快的拿到了商品信息,查看文件夹下的截图文件:
2.jpg就是我们截图的文件,打开发现图片显然是没有加载出来的,实际的效果应该是全部图片都加载出来:
放大即可看到高清的网页截图:
这个时候我们有了html可以进行静态解析数据挖掘了。
这里值得提一下的是,selenium注重对单个元素的操作,beautifulsoup注重对html页面的分析和数据分类处理,所以两者结合可以达到非常好的效果,但是大家在使用的过程中就会发现一个问题,使用selenium打开phantomjs的速度有点慢,当然大家还可以用firefox或者是chrome,这些都是selenium支持的。
Have Fun!
其实selenium还有各种各样神奇的功能,比如如果你要自动填写web应用的表单,selenium绝对比什么按键精灵好用的多的很。
0×05 匿名爬虫
有时候比较烦的是,我们使用爬虫来工作,某些情况下IP受限制,这造成了很大的麻烦,如果这个爬虫在服务器端的时候,也许还好,服务器可以提供多个可以选择的IP,但是作为一只家养的爬虫,IP被锁定以后,着实头疼。
当然所谓的匿名爬虫也就是一种以匿名方式请求目标页面,然后获取到页面结果。
0×06 匿名爬虫解决方案(from《webscraping with python》)
Tor+PySocks
PySocks设置代理
非selenium的匿名浏览设定使用方法:
import socks
import socket
from urllib.request import urlopen
#假设tor在9999号端口启动
socks.set_default_proxy(socks.SOCKS5, 'localhost', 9999)
socket.socket = socks.socksocket
print urlopen('target_web').read()
使用selenium的匿名方式:
from selenium import webdriver
#假定9999端口开启tor服务
service_args = ['--proxy=localhost:9999', '--proxy-type=socks5', ]
driver =webdriver.PhantomJS(executable_path="phantomjs.exe",service_args=service_args)
driver.get("target_url")
print driver.page_source
driver.close()
0×07 完结总结
本系列文章大概用了4篇(附:Python高级爬虫:、、)共上万字的篇幅和很多个有趣的例子来揭示了爬虫的各项技术,旨在向广大爱好者解释爬虫技术,也为需要用到爬虫的开发者提供了一些切实可行的解决方案,如果大家喜欢本系列文章,可以在评论区留下您的意见。
如果问我有什么关于爬虫和web数据挖掘的入门书籍可以看,推荐《web scraping with python》和selenium之类的书籍可以供大家参考,这些书籍仅仅是入门,如果真的要设计一款商业的爬虫,每一个细节都要谨慎处理,算法,效率都是要考虑的问题。
*原创作者:VillanCh,本文属FreeBuf原创奖励计划文章,未经作者本人及FreeBuf许可,切勿私自转载(点击上方公众号,可快速关注)来源:&顾慎为&链接:/p/002ebeb50655最近一直在用BeautifulSoup,但是语法很容易忘记。在这里做个学习总结吧。参考Beautiful Soup 4.2.0 文档功能BeautifulSoup是用来从HTML或XML中提取数据的Python库。导入使用方法:from bs4 import BeautifulSoupsoup = BeautifulSoup(html)编码soup使用Unicode编码。对象种类有四种类型:Tag,NavigableString,BeautifulSoup,Comment。BeautifulSoup将文档转化为树形结构,每个节点都是上述四种类型的Python对象。1.Tag与XML和HTML中Tag对象相同。如:soup = BeautifulSoup(Extremely bold)soup.b就是一个Tag对象。& & 1. Name& & & & tag.name 可获取,可更改& & 2. Attribute& & & & 一个Tag对象可以有多个属性,操作方法和字典相同,如上述Tag对象b就有一个class属性:& & & & soup.b['class']& & & & 或者使用get方法soup.b.get(‘class’)获取所有属性键值对:soup.b.attrstag的属性可添加、删除(del soup.b['class'])、修改,和字典方法相同。如果一个属性key对应多个value,则返回一个value的list,如:css_soup = BeautifulSoup('&')css_soup.p['class']输出:[&body&, &strikeout&]这种多个值的属性是需要在HTML中有定义的,如果并没有被定义为多值属性,则返回字符串:id_soup = BeautifulSoup('')id_soup.p['id']输出‘my id’如果转换的是XML文档,则不会存在多值属性,返回字符串。可以使用list或字符串对属性赋值。2. NavigableStringTag中的字符串即为NavigableString对象。tag.string在BeautifulSoup之外使用该类型,推荐转换为Unicode:unicode(Tag.string)tag中包含的字符串不可编辑,只能替换:tag.string.replace_with(new string)tag能够包含其他tag或字符串,而NavigableString则不能包含其他对象。不支持.content,.string,find(),只支持部分遍历文档树和搜索文档树中的属性。3. BeautifulSoup表示的是一个文档的全部内容,大部分情况可当做Tag对象,支持遍历文档树和搜索文档树的大部分属性。而在HTML或XML中并没有叫做BeautifulSoup的Tag,所以并没有name和attribute属性,但是有个特殊属性:soup.name输出u’[document]‘4. CommentComment类型是NavigableString类型的子类,BeautifulSoup中也有同样道理的一些其他类型。遍历文档树BeautifulSoup对象作为一棵树,有多个节点。对于一个节点,相对于它所在的位置,有子节点、父节点、兄弟节点。1. 子节点一个Tag可包含多个Tag以及字符串,这些都是这个Tag的子节点。而NavigableString不会有子节点。如果想要获得某个Tag,上述已提到方法:soup.tag_name通过点取属性,只能获得当前名字的第一个tag,若要获取所有,需要使用搜索文档树中的方法:soup.find_all(‘tag_name’)tag的.contents属性可将所有子节点以列表的方式输出。可通过tag的.children生成器,对所有子节点进行遍历。.contents和.children只对获取Tag的直接子节点,.descendants可用于对Tag的所有子孙节点进行遍历。如果tag只有一个NavigableString类型子节点,则可用.string获取。如果包含多个,使用.strings遍历。若输出的字符串中包含空格或空行,使用.stripped_strings去除。2. 父节点当前节点的父节点:.parent当前节点的所有父辈节点:.parents3. 兄弟节点拥有同一父节点的节点之间。.next_sibling.previous_sibling同理,所有兄弟节点:.next_siblings.previous_siblings指向下一个或上一个解析对象:.next_element.previous_element.next_elements.previous_elements搜索文档树经常使用的两种方法:find(str)和find_all(str)。其中的str,代表了tag的name。可以是纯字符串、正则表达式、列表(任一匹配就满足条件,是或运算)、True(返回所有Tag节点不返回字符串节点)。另一种入参不是str,而是method。此方法是一个函数,只接受一个元素入参,若此函数返回True表示入参匹配要求。例如:def has_class_but_no_id(tag):&& & return tag.has_attr(‘class’) and not tag.has_attr(‘id’)综上,过滤器包括:纯字符串、正则表达式、列表、True、方法这几种。1. find_all(name,attrs,recursive,text,**kwargs)该方法搜索当前节点的所有tag子节点。name参数:指的是tag的name属性,字符串对象自动忽略。过滤器可以使用全部种类。keyword参数:如果一个入参指定了名字,但是并不是上述提到的入参名字,搜索时会把该入参当做是tag的属性来搜索。例如:soup.find_all(id=’link2′)会返回tag中存在属性id,并且id对应的值是link2的tag。以上方法可使用除方法之外的所有过滤器。某些特殊属性不能这样直接使用,则使用如下方法:soup.find_all(attrs={“key”:”value”})例如要使用class属性进行搜索,由于class是python中的保留字,不能直接写成入参,目前有两种方法:soup.find_all('tag.name',class_='class_value')soup.find_all('tag.name',attrs={'class':'class_value'})class_方法可以使用全部过滤器。另外,因为class是一个多值属性,所以只需要匹配一个值,就可以得到结果,所谓的不完全匹配。使用完全匹配时,过滤器中的字符顺序需要和实际相符合才能得到对应结果。text参数:搜索的是Tag中的字符串内容,可使用全部过滤器。limit参数:限制返回数量。recursive参数:find_all()默认是搜索当前节点的所有子孙节点,若只需要搜索直接的子节点,则设置recursive=False。find_all()是实际当中用的最广泛的。因此有了等价的简化版:soup.find_all('a')soup('a')2. find(name,attrs,recursive,text,**kwargs)find()方法等价于find_all(limit=1),返回符合条件的第一个对象。区别在于,前者直接返回结果,后者返回只有一个元素的列表。若没有对象符合条件,前者返回None,后者返回空列表。它也有简化版:soup.find('head').find('title')soup.head.title除了find()和find_all()之外还有一些搜索的方法:find_parent()find_next_sibling()find_previous_sibling()上面三种可以在后面加’s'表示所有。find_next()find_previous()find_all_next()find_all_previous()3. CSS选择器Tag或BeautifulSoup对象的.select()方法。修改文档树暂略输出prettify()将文档树格式化之后输出。若不注重格式,则可使用python的str()或unicode()。如果想得到tag中包含的文本内容,使用get_text(),可获取到当前节点的文本,以及子孙节点中的文本。返回的是Unicode。可以指定参数设置分隔符如get_text(“|”)是以“|”作为分隔符。get_text(strip=True)可去除文本前后的空白。或者用.stripped_strings进行遍历。文档解析器BeautifulSoup的第一个入参是文档,第二个入参是文档解析器,默认情况下的优先顺序是:lxml, html5lib,python标准库。其中只有lxml支持xml文档的解析。编码soup使用Unicode编码。BeautifulSoup进行了编码检测并自动转为Unicode。BeautifulSoup对象的.original_encoding属性来获取自动识别编码的结果。当然这样比较慢,有时候会出错。可以在创建BeautifulSoup对象时,指定入参from_encoding来告知文档的编码方式。有时候转码时有些特殊字符替换成了特殊的Unicode,可通过BeautifulSoup对象的.contains_repalcement_characters属性来判断是否有此情况,为True即为有特殊替换。输出编码统一为UTF8,若想要其他的编码,则和一般的python字符串相同,需要进行手动设置。使用chartdet库可提高编码检测效率。【今日微信公号推荐↓】更多推荐请看《》其中推荐了包括技术、设计、极客&和&IT相亲相关的热门公众号。技术涵盖:Python、Web前端、Java、安卓、iOS、PHP、C/C++、.NET、Linux、数据库、运维、大数据、算法、IT职场等。点击《》,发现精彩!Python开发者(PythonCoder) 
 文章为作者独立观点,不代表微头条立场
的最新文章
来看看盲人程序员是如何编程的。来看看盲人程序员是如何编程的。本文介绍了python多版本管理工具pyenv的安装和使用。(点击上方公众号,可快速关注)来源:伯乐在线专栏作者 - Daetalus链接:http://python.(点击上方公众号,可快速关注)英文:Melissa Bierly译文:伯乐在线专栏作者 - 小米云豆粥链接:1(点击上方公众号,可快速关注)英文:brandonrose译文:伯乐在线专栏作者 - Ree Ray 链接:(点击上方公众号,可快速关注)英文:SRJOGLEKAR246译文:伯乐在线专栏作者 - 李加庆(Justi童年的马里奥,其实住在个超级现实的世界(点击上方公众号,可快速关注)来源: wzhvictor链接:https://segmentfault.co(点击上方公众号,可快速关注)来源: wzhvictor链接:https://segmentfault.co(点击上方公众号,可快速关注)来源: wzhvictor链接:https://segmentfault.co(点击上方公众号,可快速关注)来源: wzhvictor链接:https://segmentfault.coPython数据结构——二叉堆的实现(点击上方公众号,可快速关注)来源: wzhvictor链接:https://segmentfault.co(点击上方公众号,可快速关注)来源: wzhvictor链接:https://segmentfault.co(点击上方公众号,可快速关注)英文:译文: 伯乐在线 - LynnShaw 链接:(点击上方公众号,可快速关注)来源:quietin链接:/a2016nullnullnull(点击上方公众号,可快速关注)来源:wzhvictor链接:null(点击上方公众号,可快速关注)英文:Chris译文:zhangzhibo链接:http://www.zhannullPython 的一些误区 第二条null(点击上方公众号,可快速关注)来源:伯乐在线专栏作者 - selfboot链接:http://python.(点击上方公众号,可快速关注)来源:伯乐在线专栏作者 - 窗昏晓_送流年链接:http://python.j 第二条(点击上方公众号,可快速关注)来源:eric链接:/a/11null(点击上方公众号,可快速关注)来源:eric链接:/a/11(点击上方公众号,可快速关注)来源:eric链接:/a/11(点击上方公众号,可快速关注)来源:伯乐在线专栏作者 - Yusheng链接:http://python.j(点击上方公众号,可快速关注)英文:Amin Ariana译文:伯乐在线 - 乔永琪链接:http://bl(点击上方公众号,可快速关注)来源:codecodes 链接:/(点击上方公众号,可快速关注)来源:Cescfangs链接:http://fangs.in/post/pyt(点击上方公众号,可快速关注)来源:Joost van Dongen译文:伯乐在线 - XfLoops链接:(点击上方公众号,可快速关注)来源:Phil Johnson译文:伯乐在线 - JingerJoe链接:ht(点击上方公众号,可快速关注)来源:Joost van Dongen译文:伯乐在线 - XfLoops链接:n(点击上方公众号,可快速关注)来源:伯乐在线专栏作者 - yylucifer链接:http://python(点击上方公众号,可快速关注)来源:伯乐在线专栏作者 - Yusheng链接:http://python.jnull 第二条Python 格式化字符串显著提升程序员身心健康和工作效率的装备有哪些?PythonCoder人生苦短,我用 Python。分享 Python 相关的技术文章、工具资源、精选课程、热点资讯热门文章最新文章PythonCoder人生苦短,我用 Python。分享 Python 相关的技术文章、工具资源、精选课程、热点资讯Beautiful Soup 4.2.0 文档_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
Beautiful Soup 4.2.0 文档
上传于||文档简介
&&p​y​t​h​o​n​ ​B​e​a​u​t​i​f​u​l​S​o​u​p​ ..的​中​文​文​档
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩41页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢

我要回帖

更多关于 beautifulsoup4下载 的文章

 

随机推荐