数据爬取流程
指定url 发起请求 获取响应数据 数据解析 持久化存储
数据解析分类
正则 bs4 xpath
数据解析原理概述
解析的局部的文本内容都会在标签之间或标签对应的属性中进行存储 1、进行指定标签的定位 2、标签或者标签对应的属性中存储的数据值进行提取(解析)
正则解析案例
正则解析案例需要用到正则表达式爬取图片,如果对正则表达式不了解的,可以查看我之前的文章,Python正则表达式这次爬取糗事百科中的热图,糗事百科 我们打开开发者工具,可以看出来图片在 < div class=“thumb” > 标签中,src=后面就是图片的地址,因此我们用到正则表达式去获取网址:
pattenr=r’< div class=“thumb”>.?<img src="(.?)" alt.*?’
对于热图的第i页,网址为:
https://www.qiushibaike.com/imgrank/page/ + i
因此我们就可以获得每一页的网址,从而可以爬取多页的图片
import requests
import re
import os
for i in range(1,11):
url='https://www.qiushibaike.com/imgrank/page/'+str(i)
header={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"
}
if not os.path.exists('./糗图'):
os.mkdir('./糗图')
pattenr=r'<div class="thumb">.*?<img src="(.*?)" alt.*?'
page_text=requests.get(url=url,headers=header).text
imag_list=re.findall(pattenr,page_text,re.S)
for src in imag_list:
src='https:'+src
imag_data=requests.get(src).content
imag_name=src.split('/')[-1]
imag_path=r'./糗图/'+imag_name
with open(imag_path,'wb') as fp:
fp.write(imag_data)
print(imag_name,"下载成功")
print(imag_list)
然后就获得了爬取的图片了
bs4
bs4进行数据解析
数据解析的原理:
1、标签定位 2、提取标签、标签属性中存储的数据值
bs4数据解析的原理:
1.实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中 2.通过调用BeautifulSoup对象中相关的属性或者方法进行标签定位和数据提取
如何实例化BeautifulSoup对象:
from bs4 import BeautifulSoup 1.将本地的html文档中的数据加载到该对象中 fp = open(’./test.html’,‘r’,encoding=‘utf-8’) soup = BeautifulSoup(fp,‘lxml’) 2.将互联网上获取的页面源码加载到该对象中 page_text = response.text soup = BeatifulSoup(page_text,‘lxml’)
提供的用于数据解析的方法和属性:
-soup.tagName:返回的是文档中第一次出现的tagName对应的标签 soup.find(): find(‘tagName’):等同于soup.div 属性定位: soup.find(‘div’,class_/id/attr=’ ‘) soup.find_all(‘tagName’):返回符合要求的所有标签(列表) select: select(‘某种选择器(id,class,标签…选择器)’),返回的是一个列表。 层级选择器: soup.select(’.tang > ul > li > a’):>表示的是一个层级 soup.select(’.tang > ul a’):空格表示的多个层级
获取标签之间的文本数据:
soup.a.text/string/get_text() text/get_text():可以获取某一个标签中所有的文本内容 string:只可以获取该标签下面直系的文本内容
获取标签中属性值:
soup.a[‘href’]
案例(爬取三国演义):
import requests
from bs4 import BeautifulSoup
if __name__ == "__main__":
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"
}
url = 'http://www.shicimingju.com/book/sanguoyanyi.html'
page_text = requests.get(url=url,headers=headers).content.decode('utf-8')
soup = BeautifulSoup(page_text,'lxml')
li_list = soup.select('.book-mulu > ul > li')
fp = open('./sanguo.txt','w',encoding='utf-8')
for li in li_list:
title = li.a.string
detail_url = 'http://www.shicimingju.com'+li.a['href']
detail_page_text = requests.get(url=detail_url,headers=headers).content.decode('utf-8')
detail_soup = BeautifulSoup(detail_page_text,'lxml')
div_tag = detail_soup.find('div',class_='chapter_content')
content = div_tag.text
fp.write(title+':'+content+'\n')
print(title,'爬取成功!!!')
xpath解析
xpath解析原理:
1.实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中。 2.调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获。
如何实例化一个etree对象:from lxml import etree
1.将本地的html文档中的源码数据加载到etree对象中: etree.parse(filePath) 2.可以将从互联网上获取的源码数据加载到该对象中 etree.HTML(‘page_text’) xpath(‘xpath表达式’)
xpath表达式:
/:表示的是从根节点开始定位。表示的是一个层级。 //:表示的是多个层级。可以表示从任意位置开始定位。 属性定位://div[@class=’ '] tag[@attrName=“attrValue”] 索引定位://div[@class=" "]/p[3] 索引是从1开始的。
取文本:
/text() 获取的是标签中直系的文本内容 //text() 标签中非直系的文本内容(所有的文本内容)
取属性:
/@attrName ==>img/src
xpath实例1——爬取58二手房
首先打开58二手房网站,58二手房,打开开发者工具,可以知道房源信息在
标签中的h3里面
![在这里插入图片描述](https://img-blog.csdnimg.cn/bdf210eef5f84d259b2266c66ad9474e.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NzcxOTM5,size_16,color_FFFFFF,t_70
from lxml import etree
import requests
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"
}
url='https://bj.58.com/ershoufang/'
page_text=requests.get(url=url,headers=headers).text
tree=etree.HTML(page_text)
div_list=tree.xpath('//div[@class="property"]//div[@class="property-content-title"]/h3/text()')
print(div_list)
for div in div_list:
print(div)
注意:该网站多次访问需要验证
xpath实例2——4K图片爬取
首先废话少说,上网站:https://pic.netbian.com/4kmeishi/index.html 打开开发者工具可以知道图片在每个li标签中,可以从li标签中的a标签获得图片的名称和链接,从而爬取图片。
import requests
from lxml import etree
import os
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"
}
if not os.path.exists(r"./美食图片"):
os.mkdir(r"./美食图片")
url='https://pic.netbian.com/4kmeishi/index.html'
response=requests.get(url=url,headers=headers)
response.encoding='gbk'
page_text=response.text
tree=etree.HTML(page_text)
li_list=tree.xpath('//div[@class="slist"]/ul/li')
for li in li_list:
alt=li.xpath('.//a//@alt')[0]
src=li.xpath("./a/img/@src")[0]
img_name=alt+'.jpg'
img_src='https://pic.netbian.com/'+src
img_data=requests.get(url=img_src,headers=headers).content
img_path=r'美食图片'+img_name
with open(img_path,'wb') as fp:
fp.write(img_data)
print(img_name,'下载成功')
xpath实例3——爬取中国城市名称
网站:https://www.aqistudy.cn/historydata/,老规矩,打开开发者工具,可以知道热门城市在div:hot的 li 标签中,而全部城市在div:all的 li 标签中,这样就很容易解析数据了。
import requests
from lxml import etree
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"
}
url='https://www.aqistudy.cn/historydata/'
page_text=requests.get(url=url,headers=headers).text
tree=etree.HTML(page_text)
hotcity_list=tree.xpath('//div[@class="hot"]//div[@class="bottom"]//li')
print("热门城市:")
for hotcity in hotcity_list:
hot_name=hotcity.xpath('./a/text()')
print(hot_name[0])
all_list=tree.xpath('//div[@class="all"]//div[@class="bottom"]//li')
print('全部城市:')
for all in all_list:
all_name=all.xpath('./a/text()')
print(all_name[0])
|