1. 正则表达式
实战案例
项目需求:爬取糗事百科指定页面的糗图,并将其保存到指定文件夹中
#!/usr/bin/env python # -*- coding:utf-8 -*- import requests import re import os if __name__ == "__main__": url = 'https://www.qiushibaike.com/pic/%s/' headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', } #指定起始也结束页码 page_start = int(input('enter start page:')) page_end = int(input('enter end page:')) #创建文件夹 if not os.path.exists('images'): os.mkdir('images') #循环解析且下载指定页码中的图片数据 for page in range(page_start,page_end+1): print('正在下载第%d页图片'%page) new_url = format(url % page) response = requests.get(url=new_url,headers=headers) #解析response中的图片链接 e = ' .*?.*?' pa = re.compile(e,re.S) image_urls = pa.findall(response.text) #循环下载该页码下所有的图片数据 for image_url in image_urls: image_url = 'https:' + image_url image_name = image_url.split('/')[-1] image_path = 'images/'+image_name image_data = requests.get(url=image_url,headers=headers).content with open(image_path,'wb') as fp: fp.write(image_data)
2.bs4解析
1 使用流程:
2 - 导包:from bs4 import BeautifulSoup
3 - 使用方式:可以将一个html文档,转化为BeautifulSoup对象,然后通过对象的方法或者属性去查找指定的节点内容
4 (1)转化本地文件:
5 - soup = BeautifulSoup(open('本地文件'), 'lxml')
6 (2)转化网络文件:
7 - soup = BeautifulSoup('字符串类型或者字节类型', 'lxml')
8 (3)打印soup对象显示内容为html文件中的内容
9 基础巩固:
10 (1)根据标签名查找
11 - soup.a 只能找到第一个符合要求的标签
12 (2)获取属性
13 - soup.a.attrs 获取a所有的属性和属性值,返回一个字典
14 - soup.a.attrs['href'] 获取href属性
15 - soup.a['href'] 也可简写为这种形式
16 (3)获取内容
17 - soup.a.string
18 - soup.a.text
19 - soup.a.get_text()
20 【注意】如果标签还有标签,那么string获取到的结果为None,而其它两个,可以获取文本内容
21 (4)find:找到第一个符合要求的标签
22 - soup.find('a') 找到第一个符合要求的
23 - soup.find('a', title="xxx")
24 - soup.find('a', alt="xxx")
25 - soup.find('a', class_="xxx")
26 - soup.find('a', id="xxx")
27 (5)find_all:找到所有符合要求的标签
28 - soup.find_all('a')
29 - soup.find_all(['a','b']) 找到所有的a和b标签
30 - soup.find_all('a', limit=2) 限制前两个
31 (6)根据选择器选择指定的内容
32 select:soup.select('#feng')
33 - 常见的选择器:标签选择器(a)、类选择器(.)、id选择器(#)、层级选择器
34 - 层级选择器:
35 div .dudu #lala .meme .xixi 下面好多级
36 div > p > a > .lala 只能是下面一级
37 【注意】select选择器返回永远是列表,需要通过下标提取指定的对象
实战案例
需求:使用bs4实现将诗词名句网站中三国演义小说的每一章的内容爬去到本地磁盘进行存储
#!/usr/bin/env python # -*- coding:utf-8 -*- import requests from bs4 import BeautifulSoup headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', } def parse_content(url): #获取标题正文页数据 page_text = requests.get(url,headers=headers).text soup = BeautifulSoup(page_text,'lxml') #解析获得标签 ele = soup.find('div',class_='chapter_content') content = ele.text #获取标签中的数据值 return content if __name__ == "__main__": url = 'http://www.shicimingju.com/book/sanguoyanyi.html' reponse = requests.get(url=url,headers=headers) page_text = reponse.text #创建soup对象 soup = BeautifulSoup(page_text,'lxml') #解析数据 a_eles = soup.select('.book-mulu > ul > li > a') print(a_eles) cap = 1 for ele in a_eles: print('开始下载第%d章节'%cap) cap+=1 title = ele.string content_url = 'http://www.shicimingju.com'+ele['href'] content = parse_content(content_url) with open('./sanguo.txt','w') as fp: fp.write(title+":"+content+' ') print('结束下载第%d章节'%cap)
3.xpath解析
常用xpath表达式
1 属性定位:
2 #找到class属性值为song的div标签
3 //div[@class="song"]
4 层级&索引定位:
5 #找到class属性值为tang的div的直系子标签ul下的第二个子标签li下的直系子标签a
6 //div[@class="tang"]/ul/li[2]/a
7 逻辑运算:
8 #找到href属性值为空且class属性值为du的a标签
9 //a[@href="" and @class="du"]
10 模糊匹配:
11 //div[contains(@class, "ng")]
12 //div[starts-with(@class, "ta")]
13 取文本:
14 # /表示获取某个标签下的文本内容
15 # //表示获取某个标签下的文本内容和所有子标签下的文本内容
16 //div[@class="song"]/p[1]/text()
17 //div[@class="tang"]//text()
18 取属性:
19 //div[@class="tang"]//li[2]/a/@href
etree对象实例化
1 - 本地文件:tree = etree.parse(文件名)
2 tree.xpath("xpath表达式")
3 - 网络数据:tree = etree.HTML(网页内容字符串)
4 tree.xpath("xpath表达式")
实战案例
- 项目需求:解析58二手房的相关数据
#解析出一级页面的标题和二级页面的价格和描述 import requests from lxml import etree headers = { 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36' } url = 'https://bj.58.com/changping/ershoufang/?utm_source=sem-baidu-pc&spm=105916147073.26420796294&PGTID=0d30000c-0000-17fc-4658-9bdfb947934d&ClickID=3' page_text = requests.get(url=url,headers=headers).text tree = etree.HTML(page_text) li_list = tree.xpath('//ul[@class="house-list-wrap"]/li') data = [] for li in li_list: #解析标题 title = li.xpath('.//div[@class="list-info"]/h2/a/text()')[0] detail_page_url = li.xpath('.//div[@class="list-info"]/h2/a/@href')[0] if detail_page_url.split('//')[0] != 'https:': detail_page_url = 'https:'+detail_page_url detail_text = requests.get(url=detail_page_url,headers=headers).text tree = etree.HTML(detail_text) #解析二级页面的描述和价格 desc = ''.join(tree.xpath('//div[@id="generalDesc"]//div[@class="general-item-wrap"]//text()')).strip(' ') price = ''.join(tree.xpath('//div[@id="generalExpense"]//div[@class="general-item-wrap"]//text()')).strip(' ') dic = { 'title':title, 'desc':desc, 'price':price } data.append(dic) #进行持久化存储 print(data)
4.pyquery
待补
转载路飞学城:https://book.apeland.cn/details/149/