python Web抓取
Posted 凌晨四点的蓝
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python Web抓取相关的知识,希望对你有一定的参考价值。
需要的模块:
python web抓取通过:
webbrowser:是python自带的,打开浏览器获取指定页面
requests:从因特网上下载文件和网页
Beautiful Soup:解析HTML
Selenium:启动并控制一个Web浏览器。selenium能够填写表单,并模拟鼠标在这个浏览器中点击 >>>这个在这里
一、项目:利用Webbrowser模块的快速翻译脚本
webbrowser.open(url) 会在默认浏览器中打开这个地址
>>> import webbrowser >>> webbrowser.open(\'http://wx3.sinaimg.cn/mw600/796df69bgy1g0ufuql7mdj20tp0x8dmc.jpg\') #将打开这个地址 True
这大概就是 webbrowser 模块能做的唯一的事情。但利用 webbrowser.open() 并配合其他知识,可以让一些事情更简便的完成。
打算做个脚本:把剪贴板上的英文词语自动在Google翻译中打开,只需要将单词拷贝到剪贴板,运行脚本,浏览器会打开一个新标签页,显示翻译结果
程序需要做到:
从命令行参数或剪贴板中取得单词、
打开Web浏览器,指向该单词的Google翻译
即代码需要完成的工作:
从 sys.argv 读取命令行参数
读取剪贴板内容
调用 webbrowser.open() 函数打开外部浏览器
使用命令行参数 >>>参见<<<
全部代码:
#! python3 # mapIt.py - 将地址拷贝到剪贴板,运行这个脚本,就会打开goole地图中的地址页面 #修改为翻译英文单词的功能 import webbrowser import sys import pyperclip#假如命令行没有提供参数就翻译剪贴板中的内容 url=\'https://translate.google.cn/?hl=zh-CN&tab=TT#view=home&op=translate&sl=en&tl=zh-CN&text=\' if len(sys.argv)>1: url=url+sys.argv[1] else: url=url+pyperclip.paste() print(url) webbrowser.open(url)
1.1弄清楚URl
首先你要弄清楚,对于指定的单词,要到底使用怎样的URl。你在浏览器中打开 http://translate.google.com/ 并查找一个单词时,地址栏中的URL看起来像这样
https://translate.google.cn/?hl=zh-CN&tab=TT#view=home&op=translate&sl=en&tl=zh-CN&text=cute
其中cute是你想要查找的单词, sl=en&tl=zh-CN 代表你将英语翻译为汉语。其他的一些数据我猜想则是用来定制网站的。但如果我们尝试将 cute 替换为任何想翻译的英文词语,发现也是可以的即url为
https://translate.google.cn/?hl=zh-CN&tab=TT#view=home&op=translate&sl=en&tl=zh-CN&text=keyword #keyworld是你要翻译的英文单词
1.2处理要处理的参数
准备先取得命令行传递的参数去翻译,假如命令行没有传参数,就以剪贴板上的内容为准
if len(sys.argv)>1: #来判断命令行的参数是否只有一个 url=url+sys.argv[1] else: url=url+pyperclip.paste()
1.3.批处理文件内容
@py.exe C:\\Users\\Administrator.SC-201605202132\\AppData\\Local\\Programs\\Python\\Python37\\mapIt.py %*
#假如这行写了@pasue的话运行程序后cmd窗口会不消失
待改进:
可以继续向命令行传入参数来指定更多的翻译方式
可以将返回值取回来显示在cmd窗口中、或者过段时间就关闭打开的界面
大佬的想法:>>>详细信息<<<
二、用requests模块从Web下载文件
requests 模块让你很容易从Web下载文件,不必担心网络错误、连接问题和数据压缩。这比 urllib2 模块要更方便使用
2.1安装 requests 模块 >>>详细信息<<<<
命令行运行:
pip install requests
2.2用requests模块下载一个网页
使用 requestes.get(url) 接受一个要下载的URL字符串会返回一个Response对象,其中包含了Web服务器对你的请求作出的响应。通过检查ResPonse对象的 status_code (状态码)属性,我们可以确认对这个URL的请求是否成功,如果该值等于 resquests.codes.ok 就说明成功了
>>> import requests >>> res=requests.get(\'http://www.gutenberg.org/cache/epub/1112/pg1112.txt\') >>> type(res) <class \'requests.models.Response\'> >>> res.status_code==requests.codes.ok True >>> len(res.text) #注意这里是text不是txt 178981 >>> >>> print(res.text[:100]) The Project Gutenberg EBook of Romeo and Juliet, by William Shakespeare This eBook is for the us
也可以用来请求一个普通的地址,但似乎还没想到有什么用,或许能用来取得上面翻译的内容然后在本地显示?
2.2检查错误
我们可以通过判断 requests.codes.ok 值与Response对象的 status_code 属性值是否相等来了解下载是否成功。检查成功还有另外一种更简单的办法,就是在Response对象上调用 raise_for_status() 方法。如果下载出错,就会抛出异常。如果下载成功就什么也不做。
>>> res=requests.get(\'http://inventwithpython.com/page_that_does_not_exist\') >>> res.raise_for_status() Traceback (most recent call last): File "<pyshell#30>", line 1, in <module> res.raise_for_status() File "C:\\Users\\Administrator.SC-201605202132\\AppData\\Local\\Programs\\Python\\Python37\\lib\\site-packages\\requests\\models.py", line 940, in raise_for_status raise HTTPError(http_error_msg, response=self) requests.exceptions.HTTPError: 404 Client Error: Not Found for url: http://inventwithpython.com/page_that_does_not_exist >>>
raise_for_status() 方法是一种很好的方式,来帮助我们确认下载是否成功,当我们的程序应该在下载出错是停止,这就是一个好方法,假如下载出错后可以继续运行,我们就可以使用 try..except 语句把它包裹起来,处理这一错误,不让程序崩溃
import requests res=requests.get(\'http://inventwithpython.com/page_that_does_not_exist\') try: res.raise_for_status() except Exception as exc: print(\'这里出现了一个错误:\'+str(exc)
三、将下载的文件保存到硬盘
一旦网页被下载了后,他就是我们程序中的数据我们可以使用标准的 open() 与 write() 方法来将web页面保存到计算机本地,但要注意,需要以“写二进制”模式打开文件,即向函数传入字符串 \'wb\' ,代替更常被使用的\'a\'、\'w\'、\'r\'。以此写入二进制数据,这是为了保存文本中的“Unicode编码”。
Unicode是为每种语言中的符号和文字都制定一种独特的编码,这个标准让让计算机实现跨语言、跨平台的文字转换及处理,关于Unicode编码的更多信息,你可以点击: >>>了解更多<<<
import requests res=requests.get(\'http://www.gutenberg.org/cache/epub/1112/pg1112.txt\') res.raise_for_status() playFile=open(\'RomeoAndJuliet.txt\',\'wb\') #这会在你电脑上创建一个名为RomeoAndJuliet的文本文件
for chunk in res.iter_counter(100000): playFile.write(chunk) playFile.close()
Response对象的 iter_counter(size) 方法每次回返回一段内容,每一段都是bytes数据类型,你需要指定size的大小,通常100000是一个不错的选择,配合for循环来使用,这保证了 requests 模块在下载巨大的文件时也不会占用太多内存
回顾一下从下载到保存文件的全过程:
调用 requests.get(url) 下载文件
用 \'wb\' 调用 open() ,以写二进制打开一个新文件
利用Response的 iter_content() 方法来分段获得部分大小
利用文件对象的 write() 方法写入
关闭文件对象
四、用BeautifulSoup模块解析HTML
当使用 requests.get() 获得HTML网页文件后,可以通过 Beautiful Soup 模块中的一些方法帮助我们从网页中找到自己所需要的信息。
Beautiful Soup 是一个模块,用于从HTML页面中提取信息, Beautiful Soup 模块的名称是bs4.
安装:
命令行运行
pip install beautifulsoup4
导入
import bs4
要注意名称的不同
4.1从HTML创建一个BeautifulSoup对象
bs4.BeautifulSoup() 函数调用需要一个字符串,其中包含要解析的HTML。 bs4.BeautifulSoup() 函数返回一个 BeautifulSoup 对象。
>>> import bs4 >>> import requests >>> res=requests.get(\'http://baidu.com\') >>> res.raise_for_status() >>> noStartSoup=bs4.BeautifulSoup(res.text)#注意传入的参数是res.text,并且是返回一个对象 >>> type(noStartSoup) <class \'bs4.BeautifulSoup\'>
这个这个传入的参数也可以是一个File对象,可以从硬盘加载一个HTML文件。
>>> exampleFile=open(\'example.html\') >>> exampleSoup=bs4.BeautifulSoup(exampleFile) >>> type(exampleSoup) <class \'bs4.BeautifulSoup\'> >>>
有了 BeautifulSoup 对象以后,就可以利用对象方法,来定位HTML文档中特定的部分。
4.2用select()方法寻找元素
select() 接受一个css选择器字符串来返回一个标签对象的列表,(这个标签是 BeautifulSoup 表示一个HTML元素的方式);标签值可以传给 str() 函数,显示他们代表的HTML标签;标签值还有 getText() 方法和 attr 属性,前者返回该元素的文本或内部的HTML,后者返回一个字典,包含这个HTML元素的所有HTML属性
常见的一些css选择器
传递给select()方法的选择器 | 将匹配。。。 |
soup.select(\'div\') | 所有名为<div>的元素 |
soup.select(\'#author\') | 所有id为author的元素 |
soup.select(\'.notice\') | 所有类名为notice的元素 |
soup.select(\'div span\') | 所有<div>中的<span>元素 |
soup.select(\'div > span) | 所有直接在<div>内的<span>元素,中间没有其他元素 |
soup.select(\'input[name]) | 所有名为<input>,并有一个name属性,其值无所谓的元素 |
soup.select(\'input[type="button"]) | 所有名为<input>,并有一个type属性,其值为button的元素 |
>>> exampleFile=open(\'example.html\') >>> exampleSoup=bs4.BeautifulSoup(exampleFile) >>> type(exampleSoup) <class \'bs4.BeautifulSoup\'> >>> elems=exampleSoup.select(\'#author\') >>> type(elems)#返回值是一个列表 <class \'list\'> >>> len(elems)#匹配的个数 1 >>> elems[0].getText()#列表其中一个值得getText()方法,返回该元素的文本 \'Al Sweigart\' >>> str(elems[0])#标签值传递给str()方法,返回这个HTML标签 \'<span id="author">Al Sweigart</span>\' >>> elems[0].attrs#标签值的attrs属性,返回标签值的所有HTML属性,是一个字典 {\'id\': \'author\'}
返回的是一个列表,比如寻找p元素,主义里面的比较
>>> elems=exampleSoup.select(\'p\') >>> type(elems) <class \'list\'> >>> len(elems) #返回所有的匹配对象 3 >>> elems[0].getText() \'\\nDownload my Pythonbook from\\nmy website.\\n\' >>> elems[1].getText() \'Learn Python the easy way!\' >>> elems[1].attrs#注意这里,与下面对比,你可能就会更加清楚“HTML属性”指的是什么 {\'class\': [\'slogan\']} >>> elems[0].attrs#注意 {} >>> str(elems[1]) \'<p class="slogan">Learn Python the easy way!</p>\' >>> str(elems[0]) \'<p>\\nDownload my <strong>Python</strong>book from\\n<a href="http://inventwithpython.com">my website</a>.\\n</p>\'
4.3取得元素的属性数据
标签对象(注意在返回的列表里)的 get() 方法让我们很容易从元素中获取属性值。向该方法传入一个属性名称的字符串,它将返回该属性的值
>>> import bs4 >>> exampleFile.close() >>> exampleSoup=bs4.BeautifulSoup(open(\'example.html\')) >>> spanElem=exampleSoup.select(\'span\')[0] >>> str(spanElem) \'<span id="author">Al Sweigart</span>\' >>> spanElem.get(\'id\')#返回Id属性的值 \'author\' >>> spanElem.get(\'some_noneexitstent_addr\')==None#因为没有这个属性名称,所以结果为None True >>> spanElem.attrs {\'id\': \'author\'} >>>
以上是关于python Web抓取的主要内容,如果未能解决你的问题,请参考以下文章
Python爬虫编程思想(145):使用Scrapy Shell抓取Web资源