hello,小伙伴们,上次给大家分享了如何使用python的正则匹配爬取百思不得姐的网站代码,虽然说正则匹配爬取网站的执行效率高,但是正则匹配的规则编写着实是令人头痛的一件事。今天给大家分享一篇使用xpath来爬取百度贴吧里面的图片的文章,对比下上一篇的文章,我们就可以看出xpath的简单易用。
XPath,全称 XML Path Language,即 XML 路径语言,它是一门在 XML 文档中查找信息的语言。最初是用来搜寻 XML 文档的,但同样适用于 HTML 文档的搜索。所以在做爬虫时完全可以使用 XPath 做相应的信息抽取。
说到xPath的话,XPath Helper 这款强大的Chrome插件要和大家分享下。
xpath helper插件是一款免费的chrome爬虫网页解析工具。可以帮助用户解决在获取xpath路径时无法正常定位等问题。该插件主要能帮助你在各类网站上通过按shift键选择想要查看的页面元素来提取查询其代码,同时你还能对查询出来的代码进行编辑,而编辑出的结果将立即显示在旁边的结果框中。
xpath helper这款插件的安装是在谷歌的网上应用店里面搜索xpath helper,点击添加即可。当然是用谷歌浏览器的话需要科学上网才行,这个自行解决,若是不行的话可以在微信后台咨询我,我发给大家。具体演示如下图:
安装完成后就可以看到浏览器的右上角会有一个黑色的X图标。如图即代表安装成功。
这个安装成功以后,接下来让我们来步入今天的正文。打开百度贴吧地址:https://tieba.baidu.com,然后在搜索框输入想要搜索的贴吧内容,如‘海贼王’,可以看到链接栏的展示地址以及携带参数。如下:
然后我们点击第二页,第三页寻找链接上的规律,可以看到第二页时pn=50,第三页为pn=100,我们可以得知页面的参数步长为50,以此类推。如下图:
综上所述我们发现我们所需要携带的参数有:kw即搜索的关键词,以及显示的内容是第几页的内容。
我们的目标是爬取对应贴吧下面的帖子里面的图片,接下来让我们运用xpath插件来定位页面的元素,找到每个贴子对应的网址,例如,我们搜索的是海贼王,那么我们应该提取关于海贼王贴吧下面每个贴子对应的网址,所以我们第一步目标是取出href里面的值如下图所示:
然后我们编辑相关的xpath路径取值,具体推演过程如下图所示:
最后我们使用如下代码,可以成功的取出每个帖子的相对路径。
#元素定位对应的规则
//div[@class="t_con cleafix"]/div/div/div/a/@href
然后让我们看下每个贴字里面的图片对应的元素,这个就相对简单了,我们直接定位到图片的属性,使用即可成功地取到每个图片的对应地址了。
#元素定位对应的规则
//img[@class="BDE_Image"]/@src
在前面分析了对应的xpath的语法,那么在代码中我们如何使用xpath呢,我们需要对应的lxml模块。安装代码:
pip install lxml
接下来就是展示我们代码的环节了,如下所示:
import requests
from lxml import etree
import time
class Tieba_spider(object):
def __init__(self,BaiduTie,start_page,end_page):
#请求地址
self.base_url = "http://tieba.baidu.com"
#模拟header头
self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"}
#开始页
self.start = start_page
#结束页
self.end = end_page
#贴吧名称
self.name = BaiduTie
#第一层数据解析 找到贴吧的对应链接地址
self.first_xpath = '//div[@class="t_con cleafix"]/div/div/div/a/@href'
#第二层数据解析 找到对应网址下所有的图片
self.sec_xpath = '//img[@class="BDE_Image"]/@src'
#发送请求
def send_request(self,url,params={}):
time.sleep(1)
#如果发生异常 捕获异常 try: except Exception
try:
#携带参数和头部请求地址
response = requests.get(url,params=params,headers=self.headers)
#返回请求页面内容
return response.content
except Exception:
print("程序异常")
#写入文件
def write_file(self,data,page):
print(page)
filename = "TieBa" + page
#with open(**) as f 常见的读写操作:
with open(filename,"wb") as f:
#写入文件
f.write(data)
#解析数据
def analysis_data(self,data,xpathstr):
#转换成 lxml文档
html_data = etree.HTML(data)
#取出所有的指定标签内容
data_list = html_data.xpath(xpathstr)
return data_list
#开始调用
def start_work(self):
for page in range(self.start,self.end+1):
pn = (page - 1) * 50
params = {
"kw":self.name,
"pn":pn,
"fr":"search"
}
#发送第一次页面请求
first_data = self.send_request(self.base_url+'/f?',params)
#提取自连接 每一条单独的帖子
first_data_list = self.analysis_data(first_data,self.first_xpath)
#将每一条的数据请求
for link in first_data_list:
#拼接请求地址
link_url = self.base_url + link
#请求每个href里面的页面
second_data = self.send_request(link_url)
#二次解析 去取每个帖子里面的图片 地址 请求数据
second_list = self.analysis_data(second_data,self.sec_xpath)
#print(second_list)
for imgurl in second_list:
#请求每个图片的内容
img_data = self.send_request(imgurl)
#字符串切片 截取字符串末尾15个字符作为文件名
page = imgurl[-15:]
self.write_file(img_data,page)
if __name__ == "__main__":
BaiduTie = input("请输入贴吧名字:")
start_page = 1
end_page = 1
#实例化类
tool = Tieba_spider(BaiduTie,start_page,end_page)
#调度方法
tool.start_work()
## from lxml import etree 从lxml模块导入etree方法
## import requests 导入requests请求模块
## class Tieba_spider(object): 创建类对象
## def __init__(self,BaiduTie,start_page,end_page):
## 定义类的时候,若是添加__init__方法,那么在创建类的实例的时候,实例会自动调用这个方法
标签:xpath,__,self,爬取,start,data,page,百度 From: https://blog.51cto.com/u_15924937/5975823