python网络爬虫-爬取虎扑步行街数据

前言

由于虎扑页面的限制,因为访问虎扑步行街的第11个页面就需要用户进行登录,鉴于此时技术还没有学全,只能爬取1到10的页面。

抓取什么数据

  • 帖子名称
  • 帖子链接
  • 发帖人
  • 发帖人链接
  • 发帖时间
  • 帖子回复数
  • 帖子浏览数
  • 最后回复帖子的人
  • 最后回复的时间

如何抓取数据

  • 首先我们发现这个页面是用gzip进行压缩的,gzip是用utf-8进行编码的,也就是我们抓取的页面是用utf-8编码的,而r.text返回的是unicode编码的字符串,如果我们直接用就会出现乱码,因此,我们用r.content,返回的bytes数据(抓取音频,文件),然后将这个页面从utf-8解码为unicode编码

    html = r.content
    html = html.decode('utf-8') #将utf-8解码为unicode
    

  • 抓取数据对应的字段的html标签(代码中看)

用Mongodb存放抓取到的数据

  • 需要注意的问题,就是可能会出现本来在第一页的帖子,然后凉了啥的,被顶到了第二页,那么这时候就不能存放在数据库中,所以每次插入数据要进行判断一下

代码

import requests
from bs4 import BeautifulSoup
import time
from pymongo import MongoClient

def get_page(link):
    data_list = []
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0"
    }
    r = requests.get(link, headers=headers)
    html = r.content
    html = html.decode('utf-8') #将utf-8解码为unicode
    soup = BeautifulSoup(html, 'lxml')
    for_list = soup.find('ul', class_="for-list")
    for_list = for_list.find_all('li')
    for each_for in for_list:
        # 帖子名称
        for_name = each_for.find('div', class_="titlelink box").a.text.strip()
    
        # 帖子链接
        for_link = each_for.find('div', class_="titlelink box").a['href']
    
        for_link = 'https://bbs.hupu.com' + for_link
    
        # 作者
        for_writer = each_for.find('div', class_="author box").a.text.strip()
        
        # 作者链接
        for_writer_link = each_for.find('div', class_= "author box").a['href']

        # 帖子创建时间
        for_createtime = each_for.find('div', class_= "author box")
        # 获取节点的所有子节点,然后发现时间在列表中第6项
        for_createtime = for_createtime.contents   
        for_createtime = for_createtime[5].text.strip()

        # 回复数
        for_reply_numbers = each_for.find('span', class_= "ansour box").text.split('/')[0].strip()

        # 浏览数
        for_see_numbers = each_for.find('span', class_= "ansour box").text.split('/')[1].strip()

        # 最后回复用户
        for_last_reply_user = each_for.find('div', class_="endreply box").span.text.strip()
        
        #最后回复时间
        for_last_reply_time = each_for.find('div', class_="endreply box").a.text.strip()
        
        data_list.append([for_name, for_link, for_writer, for_writer_link, for_createtime, for_reply_numbers,for_see_numbers, for_last_reply_user,for_last_reply_time])
    return data_list

class sort_by_Mongodb:
    def __init__(self, db_host, db_port, db_name, coll_name):
        self.db_host = db_host
        self.db_port = db_port
        self.db_name = db_name
        self.coll_name = coll_name
        self.client = MongoClient(host=self.db_host, port=self.db_port)
        self.db = self.client[self.db_name]
        self.coll = self.db[self.coll_name]
    
    def update(self, query, insert_data):
        # query表示查询条件, insert_data表示更新的数据,其实在本例中就是要插入的数据
        self.coll.update_one(query, {'$set':insert_data}, upsert=True)
        # upsert (optional): If True, perform an insert if no documents match the filter.


def main():
    link = "https://bbs.hupu.com/bxj-"
    # 超过第10个页面就需要登录了。。。。
    for i in range(1,11):
        link_temp = link + str(i)
        data_list = get_page(link_temp) #返回的是列表的列表
        a = sort_by_Mongodb("localhost", 27017, "hupu", "buxingjie")
        for each in data_list:
            insert_dict = {
                "帖子名称": each[0],
                "帖子链接": each[1],
                "发帖人": each[2],
                "发帖人链接": each[3],
                "发帖时间": each[4],
                "贴子回复数": each[5],
                "帖子浏览数": each[6],
                "最后回复帖子的人": each[7],
                "最后回复时间": each[8]
            }
            # 帖子链接肯定是不一样的,因此把这个作为筛选条件
            a.update({"帖子链接": each[1]}, insert_dict)
        print("第"+ str(i)+ "页面存取完成!!!!!!!!!!!")
        time.sleep(2)

if __name__ == "__main__":
    main()

结果截图

图片.png

图片.png

一共抓取到1151条贴子,对于10个页面来说,好像差不多吧~

发布了29 篇原创文章 · 获赞 6 · 访问量 451

猜你喜欢

转载自blog.csdn.net/weixin_42100456/article/details/103921254
今日推荐