Eastmoney-Spyder:股吧网页数据抓取分析(一)

本文详细介绍了如何通过Python爬虫抓取股吧的阅读、评论、标题、作者和更新时间等数据,并解析网页结构获取总页数。在过程中遇到动态加载数据的问题,通过分析HTML源码和使用Chrome的开发者工具找到解决方案。虽然遇到部分帖子结构不同、IP被屏蔽等问题,但最终成功实现了数据抓取。
摘要由CSDN通过智能技术生成

一、项目说明

数据来源:热门个股吧
数据字段:阅读、评论、标题、作者、更新时间
实现功能:读取每个股吧的全部页面的数据并写入excel表中

二、实施过程

1.明确获取网页中哪些数据

在这里插入图片描述

我们需要抓取的是全部发帖信息的阅读评论标题作者最后更新时间这五个字段的数据,我一开始想也不是很难,解析一下网页匹配一下对应的标签值就可以了,但后面还是出现了各种各样的问题,需要大家注意一下。


2.查看网页源代码分析结构

① 网页源代码

首先打开网页的开发者工具(Ctrl+Shift+i),在源代码中查找对应字段的标签结构。

网页结构
从图中可以看出,这五个字段分别位于<span></span>行标签内,对应的属性分别是"l1 a1"、"l2 a2"、"l3 a3"、"l4 a4"、"l5 a5"。想必大家已经有思路了,我们可以通过先获取网页代码,再解析网页查询对应的五个字段,最后做一个提取就可以了。

五类字段

② 网页链接

【某一股吧:300059】
点击查看网页链接结构:首页第二页
可以看出个股吧链接主要由三部分组成:list、名称代码、页数

I.全部个股吧的数字代码

全部个股吧在这里插入图片描述
II. 翻页数据

翻页数据

如何得到不同股吧的所有翻页数据,着实让我找了好久,各种资源我都找了可惜还是没有发现,突然无意之中我找到了解决办法,我直接一个好家伙!

跟上述的五类字段一样,我们查看一下页数的代码字段,如下图所示:
在这里插入图片描述
我的第一个办法是直接解析网页后找到<span></span>标签下的sumpage属性,其内容即为总页数,本来以为原来这么好获取,结果解析完才发现,pagernums里的内容是动态的,即span.on是会随页而变化的,故直接requests并不能获取到,但是还是被我发现了玄机!
在这里插入图片描述
大家可以看data-pager这里,里面的内容是list,300059_|452885|80|2,我对比了几个页面后发现其中数字分别代表的是:

300059:股吧数字代码
452885:该股吧共发帖45288580:每个页面分别有80条贴子 
2:当前所处页面为第2

那么这时候,我们就可以直接用累积多年的算力(小学除法)算出该股吧共有452885/80=5661.0625,向上取整共5662页!如果你也脱口而出好家伙的话,请在屏幕下方打出来!


3.需要具备的功能

基本问题解决了,我们可以开始编写代码了。这部分不讲代码原理,只解释代码功能。如果代码存在问题或不清楚的话,欢迎大家在下方留言,我一定及时回复。

① 获取网页源代码

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        print("获取网页内容失败!")

② 解析网页并提取数据字段

def parsePage(html):
    list = [] # 我用的二维数组存储
    read = []
    comment  = []
    title  = []
    author  = []
    time  = []
    try:
        # print(html)
        soup = BeautifulSoup(html, "html.parser")
        for each in soup.find_all('span', 'l1 a1'):
            if '万' in each.string:
                each.string = each.string[:-2]
            read.append(each.string)
        read = read[1:] # read[0] == '阅读'
        list.append(read)
        for each in soup.find_all('span', 'l2 a2'):
            comment.append(each.string)
        comment = comment[1:]  # comment[0] == '评论'
        list.append(comment)
        for each in soup.find_all('span', 'l3 a3'):
            first = each.select('a:nth-of-type(1)')
            for i in first:
                i.find_all("a")
                # print(i.title)
                title.append(i.title)
        list.append(title)
        for each in soup.find_all('span', 'l4 a4'):
            first = each.select('font:nth-of-type(1)')
            for i in first:
                i.find_all("font")
                # print(i.title)
                author.append(i.title)
        list.append(author)
        for each in soup.find_all('span', 'l5 a5'):
            time.append(each.string)
        time = time[1:] # time[0] == '最后更新'
        list.append(time)
    except:
        print("解析网页字段失败!")
    return list

③ 获取股吧总页数

基于解析的网页直接find_all也是可以的
def get_total_pages_num(url):
    try:
        chrome_options = webdriver.ChromeOptions()
        chrome_options.add_argument('--headless')
        chrome_options.add_argument('lang=zh_CN.UTF-8')
        chrome_options.add_argument(
            'User-Agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36"')
        chrome_options.add_argument('--disable-extensions')
        chrome_options.add_argument('--disable-gpu')
        chrome_options.add_argument('--no-sandbox')

        driver = webdriver.Chrome(options=chrome_options)
        driver.get(url)
        page_data = driver.find_element_by_xpath(
            '//div[@id="mainbody"]/div[@id="articlelistnew"]/div[@class="pager"]/span[@class="pagernums"]').get_attribute(
            'data-pager')
        # print(page_data)
        if page_data:
            # page_nums = re.findall('\|(\d+)', page_data[0])
            page_nums = page_data.split("|")
            # print(page_nums)
            total_pages = math.ceil(int(page_nums[1]) / int(page_nums[2]))
        driver.quit()
    except Exception as e:
        total_pages = 1

    return int(total_pages)

4.抓取结果

上述代码基本的字段已经可以实现抓取了,结果如下:

抓取结果
可以看到,我这里的时间多了年份,这是由于研究的需要,在基于一次抓取的结果上,进行二次抓取标题所带的链接网页获得的,有关二次抓取的内容,我们再下一节再和大家分享。

在这里插入图片描述


总结

在抓取过程中,我还遇到了很多问题诸如:
① 部分帖子结构不同或存在冗余该如何处理(问董秘等链接)
② 抓取过程中ip被屏蔽自动跳转页面该如何处理(代理IP池)
… …
这些内容在后续章节中再和大家分享,下期再见啦!

关于博主

知乎:南浔Pyer
CSDN:南浔Pyer
个人网站:DL小站
GitHub:LeoWang91
评论 65
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南浔Pyer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值