zoukankan      html  css  js  c++  java
  • 初识爬虫——游天下 租房信息

    昨今两天,学习了基本的爬虫,感觉很不错,写下分享分享!!!

    首先,大家都关心的问题,学习爬虫需要具备什么知识呢??大致如下:

    • python的基础知识(函数的定义、列表的操作、文件操作、正则表达式)难度:***
    • python额外知识(BeautifulSoup、requests、re(正则表达式))
    • html+css的基础知识(类选择器、id选择器以及dom)难度:******

    然后就是做应该爬虫的基本流程:

    1. 明确自己的目标,在哪个网站爬取什么数据
    2. 分析单个页面中所需数据的获取规律
    3. 将规律提炼成函数
    4. 循环遍历获取数据
    5. 保存数据
    6. 分析数据

    比如,假设我们的任务如下:

    通过这张图片我们可以获得至少两个很重要的信息:

    1. 目标网站
    2. 目标数据

    接下来就是如何去制作爬虫,故,我们要去学习相关的工具:

    1. BeautifulSoup(https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/)
    2. requests(https://cn.python-requests.org/zh_CN/latest/)

    然后,我们就可以对单个页面的数据进行分析了。例如:http://www.youtx.com/chengdu/page1/

    首先我们在浏览器中输入地址:

    然后,我们可以(这里以chrome浏览器为例)按下F12,得到下面的画面:

    然后,我们点击那个箭头:

    然后,选取我们想看的部分,比如:

    我们就先点击刚刚那个箭头,然后点击那个地方,得到如下:

    图中箭头所指即使该租房的主要信息页面,然后,我们就点进去看看:

    这儿就是我们爬虫最主要的操作空间了,我们所需要的许多信息都是从这里获取的
    还是上面说的那样,我们先按F12,然后点击箭头,然后点击我们关注的那个地方,比如说:

    我们可以通过观察html页面知道它的位置,然后,接下来的一步就是我们怎样去找到它,如果我们仔细观察,就会发现下面的信息:

    我们可以发现,它是位于class为housemessage的li的下面的,于是我们知道,如果我们要获取那个内容,就要先获取那个li标签再获得内容。
    在css中我们知道,一个类选择器可以对应着多个标签,但是一个id选择器则只能对应一个标签,于是,我们需要知道该类选择器作用于那些标签,于是,我们可以用下面的方法做(涉及js)

    然后:

    我们发现刚好只有一个,可省下了不少事情。
    通过上面的分析,于是我们知道了一个大致的思路:在html中获取类名为housemessage的元素 ——>获取需要的值。
    那么问题来了,我们如何得到html页面,且如何获取元素呢,获取元素后我们如何获取它的值呢???
    这里,我们就需要开始使用bs4模块和requests模块了。

    以www.baidu.com为例:

    # 第一步 导包
    import requests
    from bs4 import BeautifulSoup
    
    # 第二步 获取目标网页的源代码
    source = requests.get('www.baidu.com')
    # 这里我们可以看看source具有哪些方法和属性
    print(dir(source))
    print(source.__dict__)
    
    # 第三步 美化源代码
    soup = BeautifulSoup(source.text, 'html.parser')
    # 看看效果
    print(soup.prettify())
    
    # 第四步 获取标签
    print(soup.select(xxxx))
    
    # 第五步 获取标签的值
    print(soup.select(xxx).__dict__['contents'])
    
    

    通过以上,我们就可以在一个页面中获取我们想要的数据了,那么多个页面爬取也就简单了,可以去寻找每一个页面的规律,通过上面的方法,遍历获取每个页面中理解,打开,获取数据,也可以是继续获取连接,一步步深入。

    以下就是完成上述任务的代码,可以参考参考,若有不足,请指正!!!谢谢!!!

    补充一下:爬取数据我们可以在云服务器上定时爬取,这样可以简化我们的工作。请参考:https://www.cnblogs.com/JonnyJiang-zh/p/14166913.html
    ·

    # -*- coding:UTF-8 -*-
    """
    Created on 2020/12/19 16:40
    
    @author : Jonny Jiang
    """
    
    
    import requests
    import re
    from bs4 import BeautifulSoup
    import csv
    import sys
    import time
    
    def get_info(url):
        content = requests.get(url)
        soup = BeautifulSoup(content.text, 'html.parser')
        housepercity = None  # 市
        housedistrict = None  # 区
        house_area = None  # 面积
        bedroom_num = 0 # 卧室数量
        bathroom_num = 0 # 卫生间数量
        house_style = None  # 房屋户型
        amount = None  # 宜住人数
        today_price = None  # 今日价格
        owner = None  # 租房人
        money = None  # 是否收取押金
        days = None  # 最短入住天数
        score = 0  # 总体评价
        result = []
    
        # 市区匹配表达式
        addr_1_p = "housepercity = (.+);"
        addr_2_p = "housedistrict = (.+);"
    
        housepercity = re.findall(re.compile(addr_1_p), soup.prettify())[0]
        housedistrict = re.findall(re.compile(addr_2_p), soup.prettify())[0]
        house_area = re.findall('d+', soup.select('.housemessage span')[2].contents[0])[0]
        bedroom_num = re.findall('d+', soup.select('.housemessage span')[-3].contents[0])
        if not bedroom_num:
            bedroom_num = 0
        else:
            bedroom_num = bedroom_num[0]
        bathroom_num = re.findall('d+', soup.select('.housemessage span')[1].contents[0])
        if not bathroom_num:
            bathroom_num = 0
        else:
            bathroom_num = bathroom_num[0]
        house_style = (bedroom_num, bathroom_num)
        amount = re.findall('d+', soup.select('.housemessage span')[-3].contents[0])[0]
        today_price = soup.select('.part-two p span')[0].__dict__.get('contents')[1]
        owner = soup.select(".left a")[0].__dict__['attrs']['title']
        money = soup.select('.dsection-4 span')[-4].__dict__['contents'][0][1:]
        days = soup.select('.dsection-4 span')[2].__dict__['contents'][0][0]
        score_s = soup.select('.sec-1 div')[0].get('class')
        score_int = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'half': 0.5}
        tmp = ''
        if len(score_s) > 1:
            for s in score_s[1][:-4]:
                tmp += s
                if tmp in score_int:
                    score += score_int[tmp]
                    tmp = ''
        result = [housepercity, housedistrict, house_area, house_style, amount, today_price, owner, money, days, score]
    
        return result
    
    
    def main():
        page_url = 'http://www.youtx.com/chengdu/page{}/'
    
        # 保存文件名
        filename = 'test.csv'
        # 开始写入
        # filename = sys.argv[1]
        f = open(filename, 'w+', encoding='utf-8')
        csv_writer = csv.writer(f)
        csv_writer.writerow(['市', '区', '房屋面积', '房屋户型', '宜住人数', '当日出租价格', '租房人', '是否收取押金', '最短入住时间', '总体评价'])
    
        try:
            for i in range(1, 33):
                now_url = page_url.format(i)
                page = requests.get(now_url)
                soup = BeautifulSoup(page.text, 'html.parser')
                url_markups = soup.select('#results>ul>li')
                for url_markup in url_markups:
                    url = url_markup.a.get('href')
                    print(url)
                    next_page = url
                    result = get_info(next_page)
                    print(result)
                    csv_writer.writerow(result)
                    time.sleep(0.5)
        finally:
    
            # 结束写入
            f.close()
    
    
    if __name__ == '__main__':
        main()
    
  • 相关阅读:
    钱多多软件制作04
    团队项目01应用场景
    HDU 4411 arrest
    HDU 4406 GPA
    HDU 3315 My Brute
    HDU 3667 Transportation
    HDU 2676 Matrix
    欧拉回路三水题 POJ 1041 POJ 2230 POJ 1386
    SPOJ 371 BOXES
    POJ 3422 Kaka's Matrix Travels
  • 原文地址:https://www.cnblogs.com/JonnyJiang-zh/p/14161852.html
Copyright © 2011-2022 走看看