爬虫-BeautifulSoup简单分析和学习
最近在学习py,整理一下自己的学习记录,算是备忘了。
py新手,仅供新手小伙伴们学习
1.BeautifulSoup中文文档地址https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#extract
概览
Class Diagram.png我们平常爬虫了解这几个类就可以了
上面这个图 我们最常用用到的就是Tag
和NavigableString
我们指导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)