需要的模块:
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'}
>>>