python 爬虫   数据抓取的三种方式 

 

常用抽取网页数据的方式有三种:正则表达式、Beautiful Soup、lxml

1.正则表达式

正则表达式有个很大的缺点是难以构造、可读性差、不易适用未来网页的变化。

提取数据步骤:创建正则对象-->匹配查找-->提取数据保存

写一段伪代码:

import re
url = 'http://xxxx.com/sdffs'
html = download(url)
re.findall('正则表达式', html)

HTML 示例: 

<html>
<div><a href='www.baidu.com'>正则</a></div>
<div>111111</div>
<div><a href='www.baidu1.com'>正则1</a></div>
<div>222222</div>
<div><a href='www.baidu2.com'>正则2</a></div>
<div>333333</div>
<div><a href='www.baidu3.com'>正则3</a></div>
<div>444444</div>
</html>

例:提取所有a标签的文本

pattern = re.compile(r'<a.*?>(.*?)</a>', re.S)

a_text = re.findall(pattern, html)

 

知识点:

findall 返回的结果是列表套元组的形式

而search一般要加group(), groups(),

re.S 可以将正则的搜索域不再是一行,而是整个HTML字符串

.*? 非贪婪匹配    .*贪婪匹配

 

 

2.Beautiful Soup

这是一个非常流行的python模块。安装命令如下:

pip  install beautifulsoup4

 使用此模块的第一步是将已下载的html内容解析为soup文档。因许多html网页格式不规范,Beautiful Soup可对其进行确定,将其调整为规范的html文件。

python爬取psd文件 怎么用python爬取数据_python数据抓取代码

 

  比如说我们想抓取每个新闻的标题和链接,并将其组合为一个字典的结构打印出来。首先查看 HTML 源码确定新闻标题信息组织形式

  可以目标信息存在于 em 标签下 a 标签内的文本和 href 属性中。可直接利用 requests 库构造请求,并用 BeautifulSoup 或者 lxml 进行解析。

 

方式一: requests + BeautifulSoup + select css选择器

# select method
import requests
from bs4 import BeautifulSoup
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'}

url = 'http://news.qq.com/'

Soup = BeautifulSoup(requests.get(url=url, headers=headers).text.encode("utf-8"), 'lxml')

em = Soup.select('em[class="f14 l24"] a')
for i in em:

    title = i.get_text()

    link = i['href']

    print({'标题': title, 
'链接': link

    })

很常规的处理方式.

 

方式二: requests + BeautifulSoup + find_all 进行信息提取

# find_all method
import requests
from bs4 import BeautifulSoup
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'}

url = 'http://news.qq.com/'

Soup = BeautifulSoup(requests.get(url=url, headers=headers).text.encode("utf-8"), 'lxml')

em = Soup.find_all('em', attrs={'class': 'f14 l24'})for i in em:

    title = i.a.get_text()

    link = i.a['href']

    print({'标题': title,
           '链接': link

    })

同样是 requests + BeautifulSoup 的爬虫组合,但在信息提取上采用了 find_all 的方式。

 

 

 

3.Lxml

Lxml是基于libxml2这一XML解析库的python封装。该模块使用c语言编写,解析速度比Beautiful Soup更快。
安装命令如下:

pip install lxml
pip install cssselect

如下代码,从html中获取class=country的ul标签下,li标签id=a的文本,获取li标签class=b的文本  

python爬取psd文件 怎么用python爬取数据_python数据抓取代码_02

 

# lxml/etree method
import requests
from lxml import etree



headers = {    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'}

url = 'http://news.qq.com/'

html = requests.get(url = url, headers = headers)

con = etree.HTML(html.text)



title = con.xpath('//em[@class="f14 l24"]/a/text()')

link = con.xpath('//em[@class="f14 l24"]/a/@href')
for i in zip(title, link):

    print({'标题': i[0],
'链接': i[1]

    })

   使用 lxml 库下的 etree 模块进行解析,然后使用 xpath 表达式进行信息提取,效率要略高于 BeautifulSoup + select 方法。这里对两个列表的组合采用了 zip 方法。

 

方式四: requests + lxml/html/fromstring + xpath 表达式

# lxml/html/fromstring method
import requests
import lxml.html as HTML



headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'}

url = 'http://news.qq.com/'

con = HTML.fromstring(requests.get(url = url, headers = headers).text)

title = con.xpath('//em[@class="f14 l24"]/a/text()')

link = con.xpath('//em[@class="f14 l24"]/a/@href')
for i in zip(title, link):

    print({'标题': i[0],'链接': i[1]

    })

跟方法三类似,只是在解析上使用了 lxml 库下的 html.fromstring 模块。

 

 

三种方式的比较

抓取方法

性能

使用难度

安装难度

正则表达式


困难

简单(内置模块)

Beautiful Soup


简单

简单(纯python)

Lxml


简单

相对困难

通常,lxml是抓取数据最好的选择,因为该方法既快速又健壮,而正则和Beautiful Soup只在某些特定场景下用。


  很多人觉得爬虫有点难以掌握,因为知识点太多,需要懂前端、需要python熟练、还需要懂数据库,更不用说正则表达式、XPath表达式这些。其实对于一个简单网页的数据抓取,不妨多尝试几种抓取方案,举一反三,也更能对python爬虫有较深的理解。长此以往,对于各类网页结构都有所涉猎,自然经验丰富,水到渠成。