练手:requests库爬取小说,Xpath基本提取语法
Xpath基本提取语法:
# Chrome辅助插件XPath Helper # Firefox辅助插件Try XPath # XPath语法: # '//'获取整个页面当中的元素,然后写标签名,然后写谓词 # '/'代表只获取直接子节点,'//'代表根节点下面 # //div[@id] 选择所有拥有id属性的div节点
# //span[@class] 选择所有拥有class属性的span节点 # //div[2] 按顺序查找第2个div节点,下标从1开始 # //div[contains(@id,'top')] 如果该属性包含了多个属性值,可以模糊查找id属性中包含top的div节点 # //span[@class='unknown-icon'] | //span[@class='show-city'] '|'可以选择多个路径 # .//a/@href 可以取到a标签下的href属性(在//之前加一个点,代表是在当前元素下获取) # //div[@id="content"]/text() text()函数可以取到id属性为"content"的div标签下面的所有文本内容
# //span//text() 第一个‘//’表示根节点下面,第二个‘//’表示获取非直接子节点
requests库爬取笔趣阁免费小说:
思路:
1.爬取小说的所有章节目录;
2.爬取小说每一章节的文本内容;
3.爬取小说所有章节的文本内容;
4.将爬取的小说内容写入到本地文件(这一步也可以放到第2步中同时进行)
import requests from lxml import etree BaseUrl = 'https://www.biqugetv.com' HEADWES = { 'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) ' 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36' }
# 获取所有小说章节目录,并存放到一个mu_url列表 def get_mu_url(url): resp = requests.get(url,headers = HEADWES) text = resp.content.decode('utf-8',errors='ignore') #print(text) html = etree.HTML(text) dd = html.xpath('//div[@id="list"]//dd') mu_url = [] for d in dd: mu_urls = d.xpath('.//a/@href') for a in mu_urls: mu_url.append(BaseUrl+a) # 由于爬取的目录链接是不完整的,可以自定义一个基础目录,将其拼接为完整的目录地址 return mu_url
# 获取一个章节的小说内容,并将其存入一个字符串txt中,然后将这个字符串写入到指定的文件中 def get_txt(mu_url): resp = requests.get(mu_url,headers=HEADWES) text = resp.content.decode('utf-8',errors='ignore') #print(text) html = etree.HTML(text) content = html.xpath('//div[@id="content"]/text()') #print(content) txt = '' for i in range(len(content)): txt = txt+content[i].strip()+'\n' # strip()去掉首位空格字符,‘\n’换行 txt = txt.replace('笔趣阁TV手机端https://m.biqugetv.com/','') # replace()可以替换不需要的字符串
# 写入文本,‘a’表示接上写入 with open('/Users/xx/Desktop/未命名文件夹/美人.txt','a',encoding='utf-8') as f: f.write(txt+'\n')
# 获取所有的小说内容 def get_all_txt(url): mu_url = get_mu_url(url)
# 循环取出目录列表中的章节目录,并将章节目录作为参数传入get_txt()中,得到每一章节的文本内容 for a in mu_url: get_txt(a) if __name__ == '__main__': url = 'https://www.biqugetv.com/45_45193/' # url是总目录的链接地址 get_all_txt(url)
resp.content和resp.text的区别:
# response.content:这个是直接从网络上面抓取的数据。 # 没有经过任何解码。所以是一个bytes类型。其实在硬盘上和网络上传输的字符串都是bytes类型。 # response.text:这个是str的数据类型,是requests库将response.content进行解码的字符串。 # 解码需要指定一个编码方式,requests会根据自己的猜测来判断编码的方式。 # 所以有时候可能会猜测错误,就会导致解码产生乱码, # 这时候应该使用'response.content.decode('utf-8')'进行手动解码。
使用lxml.etree解析html字符串和html文件的区别:
# 解析html字符串:使用'lxml.etree.HTML'进行解析,示例代码如下 htmlElement = etree.HTML(text) print(etree.tostring(htmlElement,encoding='utf-8').decode('utf-8')) ''' 解析html文件:使用'lxml.etree.parse'进行解析,这个函数默认使用的是'XML'解析器,所以如果碰到一些不规范的'HTML'代码的时候就会解析出错, 这时候就需要自己创建'HTML'解析器。 ''' parser = etree.HTMLParser(encoding='utf-8') htmlElement = etree.parse('boke.html',parser=parser)