giao!连续用了正则爬取了两个网站。博主表示是抗拒的。所以本次博主任性的选择了用xpath爬取股吧的相关信息。
咳咳,爬取网站信息,没有网址可怎么行呢?安排: http://guba.eastmoney.com/ 在打开网页之后,我们发现界面是这样的
通过查看页面,我们可以看到标红部分就是我们准备爬取的内容。当然了,在进行页面解析之前,我们还有一件事情要做。我们既然要爬取内容,就不可能只爬取一页内容对吧。我们先来分析下每一页之间有没有关联,首先我们看下后几页
https://guba.eastmoney.com/default,99_2.html
https://guba.eastmoney.com/default,99_3.html
https://guba.eastmoney.com/default,99_4.html
以此,我们判断出第一页是不是
https://guba.eastmoney.com/default,99_1.html
我们可以验证下
?,我们的猜想是正确的。因此,我们知道我们需要刚开始的链接分别为
base_url = "http://guba.eastmoney.com/"
start_url = "http://guba.eastmoney.com/default,99_1.html"
打开开发者选项,我们可以看到对应的关系
这个时候,我们的思路应该是通过xpath先把我们所要解析的单个主提先提取出来,然后循环提取、追加。
html_obj = etree.HTML(html)
# 使用xpath语法提取
li_list = html_obj.xpath('//ul[@class="newlist"]/li')
print(li_list)
print(len(li_list))
从上图我们可以看到我们已经获取了所有的<li></li>
标签。下面就是把他们每个比如阅读、评论等这些分别提取出来。
分析完成!下面就可以看下代码实现了:
item = {}
item["read"] = li.xpath("./cite[1]/text()")[0].strip()
item["comment"] = li.xpath("./cite[2]/text()")[0].strip()
item["name"] = li.xpath("./span/a[1]/text()")[0]
if li.xpath("./span/a[2]"):
item["title"] = li.xpath("./span/a[2]/text()")[0]
else:
item["title"] = ""
if li.xpath("./span/a[2]/@href"):
item["url"] = self.base_url + li.xpath("./span/a[2]/@href")[0]
else:
item["url"] = ""
item["author"] = li.xpath("./cite[3]/a/font/text()")[0]
item["date"] = li.xpath("./cite[4]/text()")[0].strip()
items.append(item)
print(items)
我们可以看到我们得到的结果是正确的。至于为什么上面添加的有判断语句,是因为每个网站都有其反爬手段,这里博主直接给出了完整代码。如果有感兴趣的童鞋,可以把判断语句去掉,自行查看验证,并修改。这样可以增强记忆。
好了,内容方面已经解析完成,下面我们就需要梳理翻页的思路了。
我们通过上面的分析
https://guba.eastmoney.com/default,99_1.html
https://guba.eastmoney.com/default,99_2.html
https://guba.eastmoney.com/default,99_3.html
https://guba.eastmoney.com/default,99_4.html
可以看到每一页之间都是有联系的,每一页的网址也只是变动了一个数字而已,并且我们通过查看网页,发现网页也只有12页,因此我们可以这样完成模拟
start_url = "http://guba.eastmoney.com/default,99_{}.html"
for i in range(1,13):
# 获取url
pageLink = start_url.format(i)
print(pageLink)
不过博主在此给出的是另一种写法
通过这种解析方式可以自动获取下一页的网址
通过这样,我们只需通过拼接就可以达到每一页的网址
#提取下一页
next_url = html_obj.xpath('//a[contains(text(),"下一页")]/@href')
if next_url:
next_url = self.base_url + next_url[0]
print(next_url)
# encoding: utf-8
'''
@author 李华鑫
@create 2020-10-07 9:20
Mycsdn:https://buwenbuhuo.blog.csdn.net/
@contact: 459804692@qq.com
@software: Pycharm
@file: 爬股吧.py
@Version:1.0
'''
import requests
import re
import time
import random
from lxml import etree
class Spider:
def __init__(self):
self.base_url = "http://guba.eastmoney.com/"
self.start_url = "http://guba.eastmoney.com/default,99_1.html"
self.headers = {
"user-agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
}
self.items = []
self.index = 1
def get_content(self, url):
"""获取url对应的内容"""
time.sleep(random.random()*3)
response = requests.get(url=url, headers=self.headers)
return response.content.decode("utf-8")
def parse_html(self, html):
"""解析html获取数据"""
# 解析html
html_obj = etree.HTML(html)
# 使用xpath语法提取
li_list = html_obj.xpath('//ul[@class="newlist"]/li')
# 循环
for li in li_list:
print(self.index)
item = {}
item["read"] = li.xpath("./cite[1]/text()")[0].strip()
item["comment"] = li.xpath("./cite[2]/text()")[0].strip()
item["name"] = li.xpath("./span/a[1]/text()")[0]
if li.xpath("./span/a[2]"):
item["title"] = li.xpath("./span/a[2]/text()")[0]
else:
item["title"] = ""
if li.xpath("./span/a[2]/@href"):
item["url"] = self.base_url + li.xpath("./span/a[2]/@href")[0]
else:
item["url"] = ""
item["author"] = li.xpath("./cite[3]/a/font/text()")[0]
item["date"] = li.xpath("./cite[4]/text()")[0].strip()
self.items.append(item)
self.index+=1
#提取下一页
next_url = html_obj.xpath('//a[contains(text(),"下一页")]/@href')
if next_url:
next_url = self.base_url + next_url[0]
html = self.get_content(next_url)
self.parse_html(html)
def save(self):
"""保存"""
with open("./股吧.txt", "a", encoding="utf-8") as file:
for item in self.items:
file.write(",".join(item.values()))
file.write("\n")
def start(self):
print("爬虫开始...")
self.parse_html(self.get_content(self.start_url))
print("爬虫结束...")
print("保存开始...")
self.save()
print("保存结束...")
if __name__ == '__main__':
Spider().start()
美好的日子总是短暂的,虽然还想继续与大家畅谈,但是本篇博文到此已经结束了,如果还嫌不够过瘾,不用担心,我们下篇见!