那些年,我爬过的北科(九)——搜索案例之爬虫编写

案例介绍

从本章开始,咱们将要开始进入最后的案例实践篇。html

在爬取数据以后,咱们通常会怎么用数据呢?通常来说,咱们可能会作一个搜索引擎,好比说咱们爬了新闻,可能会作一个新闻的搜索;爬取了小说可能作一个小说的搜索。python

本案例将要爬取北科贴吧的帖子数据,并在此基础上构建一个简单的搜索功能。数据库

百度贴吧分析

这里咱们首先打开北京科技大学的百度贴吧:tieba.baidu.com/f?kw=北京科技大学app

咱们的目标是关注帖子的标题名称,好比这个:“北邮人下载须要流量吗”“请问一下学长学姐,全国大学生数学竞赛初赛全国一等奖在我们学校”工具

还有就是咱们确定不能只爬取一页的信息,这里咱们将要爬取前1000页的信息。网站

页面分析

首先咱们打开Chrome开发者工具看一下列表如何解析。搜索引擎

这里咱们选中一个标题名称后,能够直接看到一个a标签,它的class为j_th_titspa

因此使用如下代码就能够打印出全部的标题来。3d

soup = BeautifulSoup(resp.content, "html.parser")
items = soup.find_all("a", {"class", "j_th_tit"})
for a in items:
    title = item.get_text()
    print(title)
复制代码

分页分析

页面分析完了以后就能够分析一下分页了,咱们把小箭头晃到底部分页的位置。code

能够发现分页对应的网址主要是pn的值不同。第2页对应50,第3页对应100,第4页对应150。

也就是,$$pn=(page-1)*50$$这样的关系。

爬虫编写

完成以上的分析工做以后,就能够开始实现咱们的爬虫了。

数据库操做

首先是数据库的操做,这里使用到tieba数据库的beike集合。而后保存文档的话就直接insert就行了。

def init_collection():
    client = pymongo.MongoClient(host="localhost", port=27017)
    db = client['tieba']
    return db["beike"]


def save_docs(docs):
    beike.insert(docs)

beike = init_collection()
复制代码

任务初始化

下面,咱们不编写worker,而是先进行任务的初始化。

if __name__ == '__main__':
    crawler = SimpleCrawler(5)
    crawler.add_worker("worker", worker)
    for i in range(1, 11):
        crawler.add_task({"id": "worker", "page": i})
    crawler.start()
复制代码

这里咱们首先初始化SimpleCrawler,而后给添加worker以及task

关于task,能够看到上面的代码经过循环,添加了10个任务,每一个任务的page属性不同。worker确定是爬取某一页并解析加入数据库的代码,咱们这里其实就是添加了爬取前10页的任务。

这里虽然也能够写直接添加爬取前1000页的任务,可是考虑到实际状况下任务可能会很是多,为了让任务队列不溢出,开始能够少添加一些。

Worker编写

接下来是worker的编写。

首先worker确定要有三个基础部分:下载页面、解析页面、保存数据。除此以外,由于要爬取1000页,因此还要添加新的任务来爬取剩下的990。

这里能够判断当前页码+10是否大于1000,若是不大于的话把当前页码+10的网页添加到新的任务队列中。

def worker(queue, task, lock):
    offset = (task["page"] - 1) * 50
    print("downloading: page %d" % task["page"])
    # 1. 下载页面
    resp = requests.get("http://tieba.baidu.com/f?kw="
                        "%E5%8C%97%E4%BA%AC%E7%A7%91%E6%8A%80%E5%A4%A7%E5%AD%A6&ie=utf-8&pn=" + str(offset))
    soup = BeautifulSoup(resp.content, "html.parser")

    # 2. 解析页面
    items = soup.find_all("a", {"class", "j_th_tit"})

    docs = []
    for index, item in enumerate(items):
        docs.append({
            "page": task["page"],
            "index": index,
            "title": item.get_text(),
            "href": "http://tieba.baidu.com" + item.attrs["href"]
        })
        print(task["page"], index, item.get_text())
    # 3. 保存数据
    with lock:
        save_docs(docs)

    # 4. 添加新任务
    if (task["page"] + 10) > 1000:
        queue.put({"id": "NO"})
    else:
        queue.put({"id": "worker", "page": task["page"] + 10})
复制代码

运行效果

以上就是爬虫的所有代码,运行后能够看到类型下面的结果。

经过以上代码大概爬了4万多条数据,以后的两章咱们将把这些标题当作语料库,而后对这些数据进行搜索。

说明

网站可能会常常变化,若是上述爬虫不能用的话,能够爬取我保存下来的贴吧网页:nladuo.cn/beike_tieba…

分页的格式相似于1.html、2.html、...、1000.html。

相关文章
相关标签/搜索