对lol贴吧爬取的一次记录

爬取对象

爬取需求

  • 爬取用户的发表文章的标题
  • 爬取用户的名称
  • 爬取用户的发表内容
  • 爬取帖子的发表时间
  • 将爬取的内容存放到Mongodb中
  • 实现自动翻页爬取
  • 最好改成增量爬取

工具以及使用到的库

  • PyCharm
  • requests
  • lxml
  • pymongo
  • queue

爬前小分析

首先我们进入到lol贴吧,然后查看页面,看一下我们需要爬取的内容,紫色区域内是我们需要爬取的内容

lol贴吧的首页

然后我们去检查[F12]一下,可以发现我们需要的信息在一个ul的标签里面放着,然后查看里面的li标签可以发现,第一个li标签存放的是置顶的帖子,这个不是我们的菜,略过。往下看,发现下面是清一色的li标签[class属性一样的,忽略那些推送广告的标签],这就是我们所需要的东西,然后点击其中一个文章的标题就会看到我们需要的信息[见下图]

查看代码块 及分析所需要的信息

PS:关于帖子内容的爬取 爬取到的时候再进行分析查看

开始工作

首先我们需要通过requests将网页抓取下来,然后使用lxml对这个页面进行数据的提取:

response = requests.get("https://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=0")

res = lxml.html.fromstring(response.text)

result_elements = res.xpath("//ul[@id='thread_list']//li[@class=' j_thread_list clearfix']")

此处个人看法,我们不要直接去拿文章的标题和作者,前面分析看到我们要获取的所有的信息都在ul标签里面,而且都是统一存放在样式一样的li内,我们应该先获取到所有的li这个节点的内容,去进行遍历这样会好很多

获取完成之后我们将result_elements打印一下:

result_elements打打印结果

他是一个列表,那么我们就通过循环来获取一下我们需要的内容吧。我们通过检查[F12]发现我们要获取的帖子的标题在一个div包裹的a标签中,其中divclass的值有好几个,那么我们就使用cssselect来获取他的内容比较好,不然通过xpath来获取的话可能要写很长很长,其中帖子的链接也存在于这里面的a标签处这样的话我们可以一块获取了,我们再看一下作者名字所在的位置:

作者的名字

我们可以看到,我们所定位到的地方作者名字是没有显示全的,但是可以看到在上面的那个span标签里面是显示了的,那么作者的标签我们就从上面的那个span标签来获取,如果你要说我们获取的是作者的名字,上面还显示主题作者四个字的话,我们可以使用replace将让去掉,代码如下:

for result_element in result_elements:
    res = result_element.cssselect("div.threadlist_title > a.j_th_tit ")[0]
    link = res.xpath(".//@href")[0]
    title = res.text
    res_author = result_element.cssselect("div.threadlist_author > span.tb_icon_author")[0]
    author = res_author.xpath(".//@title")[0].replace("主题作者: ","")

    print(BASE_URL+link)
    print(title)
    print(author)
    print('*' * 20)

其中BASE_URL是我们要拼接帖子地址用到的 BASE_URL = "https://tieba.baidu.com"

我们运行一下:

运行结果

下面我们就来获取文章内容以及时间,随便打开一篇帖子,然后我们按照上面的方法检查[F12]一下,我们可以看到:

帖子的部分

其实有的帖子是带有图片的,还有的是带有视频的,我们暂时不获取那些东西,我们来暂时只获取一下帖子的文字,我们看到文章部分是在一个div标签里面,其中class的值有两个,那么我们就使用cssselect来对文字进行获取:

    content_response = requests.get(BASE_URL+link)
    res_content = lxml.html.fromstring(content_response.text)
    con_res_ele = res_content.cssselect("div.d_post_content")[0]
    content = con_res_ele.xpath(".//text()")[0]

文章获取成功 空白的就是单单只有图片或者只有视频

时间呢,我们可以看到是在div包裹的span标签内部,我们可以看到这两个span标签class的值是一样的,但是不管是div还是span他们的class值都是一个,那么我们就使用xpath来获取他们:

    time_res = res_content.xpath("//div[@class='post-tail-wrap']//span[@class='tail-info']")[-1]
    time = time_res.text

这里有可能会有人说也可以使用[1]来获取呀,看下图

关于时间获取

我们可以看到这里面的class一样的span有三个,而包含时间的始终都在最后一个,所以我们使用[-1]来获取更好一点,那么我们的最终的代码打印一下结果看一看:

import requests
import lxml.html


headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"
}

BASE_URL = "https://tieba.baidu.com" # 为了拼接帖子的链接

response = requests.get("https://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=0")

res = lxml.html.fromstring(response.text)

result_elements = res.xpath("//ul[@id='thread_list']//li[@class=' j_thread_list clearfix']")



for result_element in result_elements:
    res = result_element.cssselect("div.threadlist_title > a.j_th_tit ")[0]
    link = res.xpath(".//@href")[0]
    title = res.text
    res_author = result_element.cssselect("div.threadlist_author > span.tb_icon_author")[0]
    author = res_author.xpath(".//@title")[0].replace("主题作者: ","")

    content_response = requests.get(BASE_URL+link)
    res_content = lxml.html.fromstring(content_response.text)
    con_res_ele = res_content.cssselect("div.d_post_content")[0]
    time_res = res_content.xpath("//div[@class='post-tail-wrap']//span[@class='tail-info']")[-1]
    content = con_res_ele.xpath(".//text()")[0]
    time = time_res.text

    print(BASE_URL+link)
    print("标题:",title)
    print("作者:",author)
    print("内容:",content)
    print("时间:",time)
    print('*' * 20)

结果显示

其他的

完了么?其实还没有,我们只是简单的讲这个程序写了出来,我们还需要将它封装一下,还有最重要的一点就是我们还没有完成使用MongoDb进行存储以及增量的爬取其余的见下一篇文章

本博客所有文章如无特别注明均为原创。作者:止语复制或转载请以超链接形式注明转自 止语博客
原文地址《对lol贴吧爬取的一次记录

相关推荐

发表评论

路人甲
看不清楚?点图切换

网友评论(0)