爬虫课程笔记
- 正则表达式
- python中原始字符串r的用法
- 内涵段子爬虫(已失效)
- XML和Xpath
- XPATH和LXML类库
- 认识XML
- XPATH节点选择
- 节点选取语法
- lxml库
- 重点
正则表达式
正则表达式的定义:
就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个"规则字符串",这个"规则字符串"用来表达对字符串的一种过滤逻辑
常用正则表达式的方法:
- repile(编译)
- pattern.match(从头找一个)
- pattern.search(找一个)
- pattern.findall(找所有)
- pattern.sub(替换)
替换
python中原始字符串r的用法
在python正则表达中尽可能的使用原始字符串,待匹配的字符串中看到什么就在正则表达式写什么,就不会出现问题
内涵段子爬虫(已失效)
# coding=utf-8
import requests
import re
import json
class Neihan:
def __init__(self):
self.start_url = "http://neihanshequ/"
self.next_url_temp = "http://neihanshequ/joke/?is_json=1&app_name=neihanshequ_web&max_time={}"
self.headers = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36"}
def parse_url(self,url):#发送请求
print(url)
response = requests.get(url,headers=self.headers)
return response.content.decode()
def get_first_page_content_list(self,html_str): #提取第一页的数据
content_list = re.findall(r"<h1 class=\"title\">.*?<p>(.*?)</p>",html_str,re.S)
max_time = re.findall("max_time: '(.*?)',",html_str)[0]
return content_list,max_time
def save_content_list(self,content_list): #保存
with open("neihan.txt","a",encoding="utf-8") as f:
for content in content_list:
f.write(json.dumps(content,ensure_ascii=False))
f.write("\n")
print("保存成功")
def get_content_list(self,json_str): #提取从第二页开始的json中的数据
dict_ret = json.loads(json_str)
data = dict_ret["data"]["data"]
content_list = [i["group"]["content"] for i in data]
max_time = dict_ret["data"]["max_time"]
has_more = dict_ret["data"]["has_more"]
return content_list,max_time,has_more
def run(self):#实现主要逻辑
#1.start_url
#2.发送请求,获取响应
html_str = self.parse_url(self.start_url)
#3.提取数据
content_lsit,max_time = self.get_first_page_content_list(html_str)
#4.保存
self.save_content_list(content_lsit)
has_more = True #有第二页
while has_more:
#5.构造下一页的url地址
next_url = self.next_url_temp.format(max_time)
#6.发送请求,获取响应
json_str = self.parse_url(next_url)
#7.提取数据,提取max_time
content_lsit,max_time,has_more = self.get_content_list(json_str)
#8.保存
self.save_content_list(content_lsit)
#9.循环5-8步
if __name__ == '__main__':
neihan = Neihan()
neihan.run()
XML和Xpath
XPATH和LXML类库
为什么要学习XPATH和LXML类库
lxml是一款高性能的 Python HTML/XML 解析器,我们可以利用XPath,来快速的==定位特定元素==以及获取节点信息
什么是XPATH:
XPath (XML Path Language) 是一门在 HTML\XML 文档中查找信息的语言,可用来在 HTML\XML 文档中对元素和属性进行遍历。
W3School官方文档:http://www.w3school/xpath/index.asp
认识XML
节点的概念:每个XML的标签我们都称之为节点
XML节点关系
XPATH节点选择
节点选取语法
XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。
使用chrome插件选择标签时候,选中时,选中的标签会添加属性class=“xh-highlight”
查找某个特定的节点或者包含某个指定的值的节点
选择未知节点
选取若干路径
xpath的更多语法:
https://msdn.microsoft/zh-cn/library/ms256039(v=vs.80).aspx
lxml库
使用入门:
导入lxml 的 etree 库
from lxml import etree
利用etree.HTML,将字符串转化为Element对象
Element对象具有xpath的方法
html = etree.HTML(text)
lxml 可以自动修正 html 代码
# coding=utf-8
from lxml import etree
text = ''' <div> <ul>
<li class="item-1"><a>first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a>
</ul> </div> '''
html = etree.HTML(text)
print(html)
#查看element对象中包含的字符串
# print(etree.tostring(html).decode())
#获取class为item-1 li下的a的herf
ret1 = html.xpath("//li[@class='item-1']/a/@href")
print(ret1)
#获取class为item-1 li下的a的文本
ret2 = html.xpath("//li[@class='item-1']/a/text()")
print(ret2)
#每个li是一条新闻,把url和文本组成字典
for href in ret1:
item = {}
item["href"] = href
item["title"] = ret2[ret1.index(href)]
print(item)
print("*"*100)
#分组,根据li标签进行分组,对每一组继续写xpath
ret3 = html.xpath("//li[@class='item-1']")
print(ret3)
for i in ret3:
item= {}
item["title"] = i.xpath("a/text()")[0] if len(i.xpath("./a/text()"))>0 else None
item["href"] = i.xpath("./a/@href")[0] if len( i.xpath("./a/@href"))>0 else None
print(item)
重点
### 正则使用的注意点
- `re.findall("a(.*?)b","str")`,能够返回括号中的内容,括号前后的内容起到定位和过滤的效果
- 原始字符串r,待匹配字符串中有反斜杠的时候,使用r能够忽视反斜杠带来的转义的效果
- 点号默认情况匹配不到`\n`
- `\s`能够匹配空白字符,不仅仅包含空格,还有`\t|\r\n`
### xpath学习重点
- 使用xpath helper或者是chrome中的copy xpath都是从element中提取的数据,但是爬虫获取的是url对应的响应,往往和elements不一样
- 获取文本
- `a/text()` 获取a下的文本
- `a//text()` 获取a下的所有标签的文本
- `//a[text()='下一页']` 选择文本为下一页三个字的a标签
- `@符号`
- `a/@href`
- `//ul[@id="detail-list"]`
- `//`
- 在xpath最前面表示从当前html中任意位置开始选择
- `li//a` 表示的是li下任何一个标签
### lxml使用注意点
- lxml能够修正HTML代码,但是可能会改错了
- 使用etree.tostring观察修改之后的html的样子,根据修改之后的html字符串写xpath
- lxml 能够接受bytes和str的字符串
- 提取页面数据的思路
- 先分组,取到一个包含分组标签的列表
- 遍历,取其中每一组进行数据的提取,不会造成数据的对应错乱
更多推荐
爬虫课程笔记(四)正则表达式、XML和Xpath
发布评论