首先,xpath和正则表达式在爬虫中的地位属于抓取、保存网页源数据后的数据分析。换句话说,数据提取和保存的方法其实是固定的做法,和你是xpath还是正则表达式提取无关。
其次,xpath这种提取思路是从网页源代码上的路径提取,根据xhelper的路径定位找到对应的目标内容;正则表达的思路是设定规范格式,用findall匹配到规范格式。
最后补充一个总结结论:
这些天学了xpath提取数据,urllib解析网页,re提取数据,bs4解析查找对象,requests提取网页,那么区别在哪?
xpath:借用lxml库使用xhelper路径提取
urllib和requests命令都是提取网页数据,用requests,这种方法更好。
bs4可以解析也可以查找,类型xpath用法。但还是选择更熟悉的xpath提取。
结论:用request提取内容,用xpath或者正则表达式获取。bs4和urllib先不使用
这次按照我的思路一步一步来:
第一步,解析网页拿到源代码:
import re
import requests
from lxml import etree
#第一步:解析保存网页
url="https://www."
headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"}
response=requests.get(url,headers=headers) #用requests下的get模式
#print(response) <Response [200]>是正常运行,接下来是读取
#print(response.content.decode()) #这一步就拿到了所有数据 为了方便调用 取个名字html
html=response.content.decode() #到这里基本完成解析
简化版结论
import re
import requests
from lxml import etree
#第一步:解析保存网页
url="https://www.
headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"}
response=requests.get(url,headers=headers)
html=response.content.decode()
第二步,拿到我们想要的数据
doc=etree.HTML(html) #编辑进doc中,后续用doc进行查找
# print(doc) 这个输出是<Element html at 0x203f485fbc0> 简单的element对象
#获取索引值
index=doc.xpath("//div[@class='list_num_info']/text()")
# print(index) #乱码太多 得修改里面每一个元素
new_index=[]
for e in index:
new_index.append(e.replace(" ","").replace("\n",""))
# print(new_index) #到这里 索引值获取完成
#获取书名
titles=doc.xpath("//div[@class='shici_list_main']/h3/a/text()")
#获取内容
contents=doc.xpath("//div[@class='shici_content']")
#//div[@class='shici_list_main']/div[@class='shici_content'] 到这里都是对的
#//div[@class='shici_list_main']/div[@class='shici_content']/text()但是text()就不对了 怎么回事呢? 子节点读法不对 那就不读了 后面想办法读
#老师给的这个 //div[@class='shici_content'] 也可以 先不展开 先改
new_contents=[]
for e in contents:
new_contents.append(e.xpath('string(.)').replace("\n","").replace("收起","").replace("展开全文","")
.replace("\r","").replace(" ",""))
# new_contents.append(e.xpath('string(.)')) #后读 对每一个没有text()读取的ele元素 用e.xpath('string(.)') 后读
# new_contents.append(e.replace("\n","").replace("收起","").replace("展开全文",""))
#.strip()自动去除所有空格 相当于replace(" ","")更简单 但是实测没有replace(" ","")完整性强
#print(new_contents) 也就是说目前 要提取的内容全部洗干净放好了 接下来放进一个列表之中
还是给一个简化版
doc=etree.HTML(html) #编辑进doc中,后续用doc进行查找
#获取索引值
index=doc.xpath("//div[@class='list_num_info']/text()")
new_index=[]
for e in index:
new_index.append(e.replace(" ","").replace("\n",""))
#获取书名
titles=doc.xpath("//div[@class='shici_list_main']/h3/a/text()")
#获取内容
contents=doc.xpath("//div[@class='shici_content']")
new_contents=[]
for e in contents:
new_contents.append(e.xpath('string(.)').replace("\n","").replace("收起","").replace("展开全文","").replace("\r","").replace(" ",""))
这里涉及数据清洗
//div[@class='shici_list_main']/div[@class='shici_content']
//div[@class='shici_list_main']/div[@class='shici_content']/text()
注意,直接拿到路径一般是ele对象
但是/text()拿到的实际上是文本内容
需要清洗的,不用读文本内容 for in循环创建新列表 洗干净了放进新列表
不需要清洗的,直接/text()读成要提取的内容
特殊的,需要ele后面读取的,用e.xpath('string(.)')这个也是阅读 读成字符串形式
第三步,做一个简单的列表,把我们搜集到的数据一一对应
poems=[]
for i,title in enumerate(titles):
one_poem=[]
one_poem.append(new_index[i])
one_poem.append(titles[i])
one_poem.append(new_contents[i])
poems.append(one_poem)
print(poems)
这里用到了enumerate这个循环 好处是一一对应的时候带索引 for后面第二个内容任意 我们要的主要是索引
先放到one_poem再循环到大列表之中,这一步结束。
第四步,用pandas保存现有的单页面数据
import pandas as pd
df=pd.DataFrame(poems,columns=["索引","标题","内容"])
df.to_excel("苏轼诗词.xlsx",index=None)
print("执行完毕")
这个时候文件就已经生成了,但之后一页,之后的也不复杂,做一个循环就可以