首先,xpath和正则表达式在爬虫中的地位属于抓取、保存网页源数据后的数据分析。换句话说,数据提取和保存的方法其实是固定的做法,和你是xpath还是正则表达式提取无关。
其次,xpath这种提取思路是从网页源代码上的路径提取,根据xhelper的路径定位找到对应的目标内容;正则表达的思路是设定规范格式,用findall匹配到规范格式。
最后补充一个总结结论:
这些天学了xpath提取数据,urllib解析网页,re提取数据,bs4解析查找对象,requests提取网页,那么区别在哪?
xpath:借用lxml库使用xhelper路径提取
urllib和requests命令都是提取网页数据,用requests,这种方法更好。
bs4可以解析也可以查找,类型xpath用法。但还是选择更熟悉的xpath提取。
结论:用request提取内容,用xpath或者正则表达式获取。bs4和urllib先不使用
这次按照我的思路一步一步来:
第一步,解析网页拿到源代码:
importreimportrequestsfromlxmlimportetree#第一步:解析保存网页url="https://www."headers={"user-agent":"Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/105.0.0.0Safari/537.36"}response=requests.get(url,headers=headers)#用requests下的get模式#print(response)<Response[200]>是正常运行,接下来是读取#print(response.content.decode())#这一步就拿到了所有数据为了方便调用取个名字htmlhtml=response.content.decode()#到这里基本完成解析简化版结论
importreimportrequestsfromlxmlimportetree#第一步:解析保存网页url="https://www.headers={"user-agent":"Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/105.0.0.0Safari/537.36"}response=requests.get(url,headers=headers)html=response.content.decode()第二步,拿到我们想要的数据
doc=etree.HTML(html)#编辑进doc中,后续用doc进行查找#print(doc)这个输出是<Elementhtmlat0x203f485fbc0>简单的element对象#获取索引值index=doc.xpath("//div[@class='list_num_info']/text()")#print(index)#乱码太多得修改里面每一个元素new_index=[]foreinindex: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=[]foreincontents: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=[]foreinindex: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=[]foreincontents: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()拿到的实际上是文本内容
需要清洗的,不用读文本内容forin循环创建新列表洗干净了放进新列表
不需要清洗的,直接/text()读成要提取的内容
特殊的,需要ele后面读取的,用e.xpath('string(.)')这个也是阅读读成字符串形式
第三步,做一个简单的列表,把我们搜集到的数据一个一个地对应
poems=[]fori,titleinenumerate(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保存现有的单页面数据
importpandasaspddf=pd.DataFrame(poems,columns=["索引","标题","内容"])df.to_excel("苏轼诗词.xlsx",index=None)print("执行完毕")这个时候文件就已经生成了,但之后一页,之后的也不复杂,做一个循环就可以