爬虫-BeautifulSoup简单分析和学习

2017-02-26  本文已影响633人  奇董

最近在学习py,整理一下自己的学习记录,算是备忘了。
py新手,仅供新手小伙伴们学习
1.BeautifulSoup中文文档地址https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#extract

概览
Class Diagram.png

我们平常爬虫了解这几个类就可以了

上面这个图 我们最常用用到的就是TagNavigableString

我们指导html是标记语言,我们想爬的数据都是被格式各样的标签嵌套的。
<head>数据</head>
而BeautifulSoup 简单的来说就是找标签取数据,总体来说学习成本特别低,容易上手。

我们来一步一分分析 对象的创建 以及 返回的类型

1.BeautifulSoup 的初始化

soup = BeautifulSoup(content,'lxml')
soup 是一个BeautifulSoup类型,从上面的继承关系看其实就是一个Tag类型。一个大Tag包含着无数的小Tag

2.初步定位tag

tag = soup.find('table')
返回的是一个也是tag类型
tags = soup.find_all('table')
返回的是一个ResultSet 其实就是一个list类型的子类,在bs4.element文件中有说明

3.具体定位tag

当我们获取大体的Tag对象时,我们如果想获取其中子Tag的数据
这里要分2种情况
一 。。标记有属性标记
直接再通过第二步的方法继续获取
二 。。没有属性标记 如<td></td>
str_list = tag.contents
返回一个list对象
str_list_iterator = tag.children
返回一个list_iterator

4.获取数据

首先要说一点 上面第三步说的获取具体的tag,其实通过contents和children获取的不只是Tag对象,还有NavigableString对象。这点一定要清楚。
直接通过string属性来获取就可以了

实战

爬取ip代理网站(2种不同的类型),获取代理ip。
1.西刺免费代理IPhttp://www.xicidaili.com/nn

网页源代码 我就不贴在这边了

源代码 大家自己另开的网页自己看下

通过分析源代码,我们很清楚的发现我们数据实在table标签内(而且页面只有一个table标签)
1.初始化
soup = BeautifulSoup(res.content,'lxml')
2.定位大体的Tag(这一步可以省略)
table_tag = soup.find('table')
3.定位具体的Tag
tr_list = table_tag.find_all('tr')
4.得到数据

for index,tr_tag in enumerate(tr_list):
    if index > 1:
        td_list = list(filter(lambda x:x != '\n',tr_tag.contents))
        print('ip: ' + td_list[1].string + ':' + td_list[2].string)

我们分析源码可以发现 第1,2个tr 是表头,不包含我们想要的数据,可以跳过。
在contents获取或有子节点的时候,我们会发现返回的不只有tag对象还有‘\n’字符的None类型。所以我们要用filter过滤这些噪音数据。
在过滤之后,我们可以清楚的看到 第二个tag对象时ip地址,第二个是端口号。

import requests
from bs4 import BeautifulSoup

res = requests.get('http://www.xicidaili.com/nn',headers = { 'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20' })

soup = BeautifulSoup(res.content,'lxml')
table_tag = soup.find('table')
tr_list = table_tag.find_all('tr')

for index,tr_tag in enumerate(tr_list):
    if index > 1:
        td_list = list(filter(lambda x:x != '\n',tr_tag.contents))
        print('ip: ' + td_list[1].string + ':' + td_list[2].string)

这里在请求数据的是时候,因为西刺有防爬处理。我们不能直接请求。需要模拟客户端,填写一个header

最后

如果想要自动翻页爬取的话,已西刺为例。只要在爬取一页完成,自动切换下一页就好

import requests
from bs4 import BeautifulSoup

for page in range(1,10):
    res = requests.get('http://www.xicidaili.com/%d'%page,headers = { 'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20' })
    soup = BeautifulSoup(res.content,'lxml')
    table_tag = soup.find('table')
    tr_list = table_tag.find_all('tr')
    
    for index,tr_tag in enumerate(tr_list):
        if index > 1:
            td_list = list(filter(lambda x:x != '\n',tr_tag.contents))
            print('ip: ' + td_list[1].string + ':' + td_list[2].string)
上一篇下一篇

猜你喜欢

热点阅读