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 web抓取代码不会打开链接

Python Web 抓取 - 403 错误

python web抓取并将数据写入csv

Python爬虫编程思想(145):使用Scrapy Shell抓取Web资源

Python爬虫编程思想(145):使用Scrapy Shell抓取Web资源

Python爬虫编程思想(145):使用Scrapy Shell抓取Web资源