聚焦爬虫:提取页面中指定的内容
编码流程
1指定url
2发起请求
header={
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
param={
'type':'24',
'interval_id':'100:90',
'action':'',
'start':'20',
'limit':'20'
}
data={
'cname':'',
'pid':'',
'keyword':'北京',
'pageIndex':'2',
'pageSize':'10'
}
get请求
response=requests.get(url=url,headers=headers,params=param)
post请求
response=requests.post(url=post_url,data=data,headers=header)
可以创建一个session对象发送请求,可以自动携带cookies,
session=requests.session()
response=session.get(url=url,headers=headers)
response=session.post(url=post_url,data=data,headers=header)
还可以使用代理:添加参数字典
proxie={
"https":"222.110.147.50:3128"
}
response=session.get(url=url,headers=headers,proxies=proxie)
response=session.post(url=post_url,data=data,headers=header,proxies=proxie)
3获取响应数据
.text 文本数据
.content 二进制数据
.json() json数据
json格式数据
dic_obj=response.json()
文本格式数据
page_text=response.text
二进制格式数据
img_data=response.content
4数据解析
tree=etree.HTML("page_text")
tag_list=tree.xpath('xpath表达式') 通过层级关系定位获得列表,再遍历列表取数
5持久化存储
保存为文件
with open('./pic/'+img_name+'.jpg','wb') as fp:
fp.write(img_data)
数据解析原理概述
解析局部文本内容都会在标签之间或者标签的属性值中
1,进行指定标签的定位
2,标签或者其对应属性中存储的数据值进行提取(解析)
数据解析分类
正则
ex='<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
bs4
实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
通过调用BeautifulSoup对象中相关属性或方法进行标签定位和数据提取
pip install bs4
pip install lxml
from bs4 import BeautifulSoup
对象实例化
1,将本地的html文档中的数据加载到该对象中
fp=open('./test.html','r',encoding='utf-8')
soup=BeautifulSoup(fp,'lxml')
2,将互联网上获取的页面源码加载到该对象中(常用方法)
page_text=response.text
soup=BeautifulSoup(page_text,'lxml')
方法和属性
soup.tagName 返回的是文档中第一次出现的tagName对应的标签
soup.find('div') 返回的是文档中第一次出现的tagName对应的标签同上
soup.find('div',class_='song') 通过属性值class=song定位标签
soup.findall(tagName) 返回符合要求的所有标签列表
soup.select('某种选择器(id,class,标签)'),返回的是一个列表。
层级选择器 soup.select('.tang>ul>li>a') >表示一个层级 空格表示多个层级
层级选择器 soup.select('.tang>ul a') >表示一个层级 空格表示多个层级
获取标签之间的文本值
soup.a.string 直系文本内容,不含子标签的文本
soup.a.text 可以获取某标签下的所有文本内容即使不是直系文本
soup.a.get_text() 可以获取某标签下的所有文本内容即使不是直系文本
获取标签之间的属性值
soup.a['href'] a标签的hre属性值
xpath(重点内容)
1实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中
2调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获
环境安装
pip install lxml
实例化一个etree对象
1,将本地的html文档中的数据加载到该对象中
tree=etree.parse(fielpath)
2.将从互联网获取的原码数据加载到该对象中
tree=etree.HTML("page_text")
tree.xpath('xpath表达式') 通过层级关系定位
tree.xpath('/html/head/title') 返回的是elementc对象的列表
/:表示从根节点开始定位,
一个/表示一个层级,
//:两个//表示多个层级:从任意位置开始的定位
属性值定位://div[@class='song'] 根据属性值定位标签
索引定位://div[@class='song']/p[3] 第3个P标签,索引从1开始
取标签文本值:
/text() 获取标签中真系的文本内容
//div[@class='tang']//li[5]/a/text() 得到a标签的文本值,是一个列表类型,要得到文本则:
r=tree.xpath('//div[@class='tang']//li[5]/a/text()')[0]
//text() 获取标签中真系以及非直系的文本内容 //li[7]//text() 当前及子节点的文本内容
取标签属性值:/@href
r=li.xpath('./img/@src')[0]
import requests import time from lxml import etree import os if __name__ == '__main__': #首页 url='https://cd.58.com/ershoufang/?PGTID=0d30000c-0006-685b-68dd-d19294c423fe&ClickID=2' headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' } page_text=requests.get(url=url,headers=headers).text #数据解析 tree=etree.HTML(page_text) #存储的就是lis标签对象 li_list=tree.xpath('//ul[@class="house-list-wrap"]/li') fp=open('./58.txt','w',encoding='utf-8') for li in li_list: #对li标签再次局部解析出h2下面的a标签值 # ./代表li对象本身 必须这样写*** title=li.xpath('./div[2]/h2/a/text()')[0] print(title) fp.write(title+'\n') print("OK!") if __name__ == '__main__': if not os.path.exists('./pic'): os.mkdir('./pic') url='http://pic.netbian.com/4kdongwu/' headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' } response=requests.get(url=url,headers=headers) #1此处为解决中文乱码,手动设置响应数据的编码格式为utf-8 但结果仍不能解决 # response.encoding='utf-8' page_text=response.text tree=etree.HTML(page_text) list_src=tree.xpath('//ul[@class="clearfix"]/li/a') for li in list_src: img_src='http://pic.netbian.com'+li.xpath('./img/@src')[0] img_name=li.xpath('./b/text()')[0] #2此处为解决名称为乱码,先编码为iso,再解码为gbk #较为通用的解决中文乱码的方案 img_name=img_name.encode('iso-8859-1').decode('gbk') #print(img_name,img_src) img_data=requests.get(url=img_src,headers=headers).content #取得图片二进制数据 with open('./pic/'+img_name+'.jpg','wb') as fp: fp.write(img_data) print(img_name,'下载成功!') time.sleep(1)