Reptile:requests + Xpath 爬取段子网的段子

2019/1/24 中午路飞学成 爬虫课程 实验及笔记。

Xpath是路飞爬虫课程中老师说的三种解析方式之一,前面是re正则表达式的解析方式,现在是xpath的解析方式,后面还有一个是bs4的解析方式。

re其实我理解的很困难,而且到现在都还不怎么理解这个东西到底应该怎么去组合起来,进行匹配,反而这个Xpath我个人觉得比较好理解,他就是通过一步一步的去解析网页的结构来找到你想要的东西,比如有一个三级的结构,你就可以用xpath一级一级的去往下走,直到到达你需要的点就ok了。而且还可以进行模糊查找和逻辑查找。

下面是代码:

# 需求:使用xpath对段子网的内容和标题进行解析,并存储到本地

  import os

  import requests

from lxml import etree

# 指定本地数据存储位置
if not os.path.exists('./Duan zi word'):
os.mkdir('Duan zi word')

# 获取用户输入的页码范围
start_page = int(input("Enter a start pageNum:>>>"))
end_page = int(input("Enter a end pageNum:>>>"))

# 打开文件并生成文件句柄
fp = open('Duan zi word/duanzi.txt', 'w', encoding='utf-8')

# 指定url 和请求头信息
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/65.0.3325.181 Safari/537.36'
}
for num in range(start_page, end_page + 1, 1):
url = 'http://duanziwang.com/page/' + str(num)

# 发起请求并获取返回数据:
response = requests.get(url=url, headers=headers)
if response.status_code == 200:
page_text = response.text

# 实例化etree对象,并对获取的网页数据进行初步解析
tree = etree.HTML(page_text)
article_list = tree.xpath('//article[contains(@id,"")]') # 这里是使用了模糊匹配,用contains取所有包含id的标签,这个里面和课程有点不一样,能是网站更新了吧

# 对初步解析得到的数据进行二次解析,得到标题和正文。xpath得到的Element对象都可以再次调用xpath
for li in article_list:
title = li.xpath('./div[@class="post-head"]/h1[1]/a/text()')[0] # 解析初标题的信息,存到变量中后面写入用 ./是表示在当前标签下去进行查找,当前标签就是这个的父级标签
content = li.xpath('./div[@class="post-content"]/p[1]/text()') # 解析出内容的信息。
try:
fp.write(title + ":" + "\n" + str(content[0]) + "\n\n")
print('\033[31m %s \033[m 已完成写入' % title)
except:
fp.write(title + ":" + "\n\n")
print('\033[32m索引错误\033[m \n')
else:
print("\033[41m链接访问异常,请重新尝试连接....\033[m")

做这个案例的时候碰到了一个小的问题,就是在后面进行二次解析的时候发现会有拿到的列表中有空的,你对空列表进行切片的时候就会报错,超出了列表的索引的范围,没有想到很好的办法进行解决,就尝试使用了
异常处理try 和 except进行处理,没有问题的就直接写入到文件里面去,有问题的就给放在except中去执行,只写一个列表进去,这个问题只存在在内容里面,标题是没有这样的问题的,因为标题是都有的,内
容呢可能是有些用户
没有去写吧,或者直接就吧标题当成了内容就保存,就会出现空的列表的问题。


posted @ 2019-01-24 21:51  微雨丶  阅读(130)  评论(0编辑  收藏  举报