资讯专栏INFORMATION COLUMN

python入门实践:如何爬取自如数据

peixn / 2812人阅读

摘要:简单来说就是浏览器向服务器表明身份用的。用户行为主要靠。爬取数据我们的原材料准备好了,开始爬取,可以看见用的是去,池取得随机配置组成请求。

首先代码地址奉上
https://github.com/liangyuqi/...

一、简介

use python to catch the information from ziru(彩蛋见最后

适合一起刚入门python的同学,我也是萌新,所以代码可能不是很优雅

爬取思路分析见第五部分

二、环境 Python

python --version

(mac自带)

brew install python

pip

pip --version

pip 是 Python 包管理工具,该工具提供了对Python 包的查找、下载、安装、卸载的功能

curl https://bootstrap.pypa.io/get... -o get-pip.py

sudo python get-pip.py

三、安装依赖

pip freeze >package.txt

sudo pip install -r package.txt

四、启动

cd index

chmod a+x ziru_room.py

python ziru_room.py

五、思路分析 1.反反爬虫

一般公司都有安全部门,防止大规模的撞库或者带宽挤占,那爬取的时候肯定会被拦截,定位然后律师函警告。

所以我觉得一个爬虫系统最重要的就是反 反爬虫

我们先分析一下,一般简单的反爬虫什么思路?

用户请求的Headers,用户行为,网站目录和数据加载方式

headers里面主要根据userAgent查重。userAgent 属性是一个只读的字符串,声明了浏览器用于 HTTP 请求的用户代理头的值。简单来说就是浏览器向服务器”表明身份“用的。

用户行为主要靠ip。ip的话不用讲了,和身份证号差不多,所以我们发起请求应该用动态的,同一ip多次访问就可能被拉入ip黑名单,而且会导弹定位到你的服务器所在位置。

第三个方式比较高端了,我这次没有展示。前两种是爬虫伪装成浏览器读取数据,但是第三种是模拟出一个浏览器进行用户点击提交等操作,它本身就是一个没有界面的浏览器,从填写表单到点击按钮再到滚动页面,全部都可以模拟。这时候就可以根据一些其它方式,如识别点触式(12306)或者滑动式的验证码。

整理好思路开始实现,我们的目标是实现一个动态的ip和userAgent池,每次请求伪装成不一样的来源

step1: 我们去爬取一个开放代理ip的网站。。。然后试试他开放的ip可不可用,可用的话加入我们的ip池。 详见 代码 ziru_room.py

    # 经测试可用ip
    usefulIp = []

    # 获取代理ip地址
    uriGetIp = "http://www.xicidaili.com/wt/"

    # 检测ip是否可用地址
    testGetIp = "http://icanhazip.com/"

    usefulIp = getUsefulIPList(uriGetIp, testGetIp, userAgent)
"""
获取可用的ip列表
"""
def getUsefulIPList(uriGetIp, testGetIp, userAgent):
    # 全部代理ip
    allProxys = []

    # 经测试可用ip
    usefulIp = []
    ipList = requests.get(
        uriGetIp, headers={"User-Agent": random.choice(userAgent)})

    ipData = bs4.BeautifulSoup(ipList.text, "html.parser")

    ip = ipData.select("#ip_list > tr > td:nth-of-type(2)")

    port = ipData.select("#ip_list > tr > td:nth-of-type(3)")

    protocol = ipData.select("#ip_list > tr > td:nth-of-type(6)")

    for ip, port, protocol in zip(ip, port, protocol):
        proxy = ip.get_text().strip()+":"+port.get_text().strip()
        allProxys.append(proxy)

    print("正在初始化ip数据池,请耐心等待...")

    process.max_steps = len(allProxys)

    process.process_bar = process.ShowProcess(process.max_steps)

    # 筛选可用ip
    for proxy in allProxys:
        process.process_bar.show_process()
        # time.sleep(0.05)
        try:
            theIp = requests.get(testGetIp,  headers={"User-Agent": random.choice(userAgent)}, proxies={
                "http": proxy}, timeout=1, allow_redirects=False)
        except requests.exceptions.Timeout:
            # print("超过1s")
            continue
        except requests.exceptions.ConnectionError:
            # print("连接异常")
            continue
        except requests.exceptions.HTTPError:
            # print("http异常")
            continue
        except:
            # print("其他错误")
            continue
        else:
            if (theIp.status_code == 200 and len(theIp.text) < 20):
                usefulIp.append(proxy)
            #    print(theIp.text)

    print("可用ip池为下:"+",".join(usefulIp))
    return usefulIp

step2: 构造userAgent池

  userAgent = ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
                 "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0",
                 "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10"
                 ]

这个不像ip会经常挂,所以写死问题不大。

2.爬取数据

我们的原材料准备好了,开始爬取,可以看见用的是random.choice()去ip,userAgent池取得随机配置 组成 get请求。详见 代码 ziru_room.py

def computedData(usefulIp, userAgent, ipIndex=0):
    # debugger
    # pdb.set_trace()
    fhandle = open("../output/output.txt", "a")  # 追加写入文件

    # Get请求-并传递headers
    try:
        data = requests.get("http://www.ziroom.com/z/nl/z3-r3-o2-s5%E5%8F%B7%E7%BA%BF-t%E5%8C%97%E8%8B%91%E8%B7%AF%E5%8C%97.html",
                            headers={"User-Agent": random.choice(userAgent)}, proxies={"http": random.choice(usefulIp)}, timeout=(3, 7))
        #
        pass
    except:
        print "Error: 请求失败"
        computedData(usefulIp, userAgent)
        return
        pass
    else:
        roomDate = bs4.BeautifulSoup(data.text, "html.parser")
        # 标题
        title = roomDate.select("#houseList > li > div.txt > h3 > a")
        # 地点 改版没了////
        # place = roomDate.select("#houseList > li > div.txt > h4 > a")
        # 距离
        distance = roomDate.select(
            "#houseList > li > div.txt > div > p:nth-of-type(2) > span")
        # 价格
        price = roomDate.select("#houseList > li > div.priceDetail > p.price")
        # 面积
        area = roomDate.select(
            "#houseList > li > div.txt > div > p:nth-of-type(1) > span:nth-of-type(1)")
        # 楼层
        floor = roomDate.select(
            "#houseList > li > div.txt > div > p:nth-of-type(1) > span:nth-of-type(2)")
        # 房间配置
        room = roomDate.select(
            "#houseList > li > div.txt > div > p:nth-of-type(1) > span:nth-of-type(3)")
        #
        print("北京市自如数据如下")
        fhandle.write("北京市"+time.strftime("%Y-%m-%d %H:%M:%S",
                                          time.localtime()) + "自如数据如下"+"
")

        for title, price, area, floor, room, distance in zip(title, price, area, floor, room, distance):
            last_data = {
                "名称": title.get_text().strip(),
                # "地段": place.get_text().strip(),
                "距离": distance.get_text().strip(),
                "价格": price.get_text().replace(" ", "").replace("
", ""),
                "面积": area.get_text().strip(),
                "楼层": floor.get_text().strip(),
                "房间大小": room.get_text().strip()
            }

            fhandle.write("名称:"+title.get_text().strip())
            # fhandle.write("地段:"+place.get_text().strip())
            fhandle.write("距离:"+distance.get_text().strip())
            fhandle.write(
                "价格:"+price.get_text().replace(" ", "").replace("
", ""))
            fhandle.write("面积:"+area.get_text().strip())
            fhandle.write("楼层:"+floor.get_text().strip())
            fhandle.write("房间大小:"+room.get_text().strip() + "
")

            # print  json.dumps(last_data).decode("unicode-escape")
            # print  json.dumps(last_data,ensure_ascii=False)
            print json.dumps(last_data, encoding="UTF-8", ensure_ascii=False)

        fhandle.write("************************************************"+"
")
        fhandle.close()
        print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        pass
3.其他部分

因为爬取可用的ip组成ip池,是一个比较耗时的过程,所以加入了图像化的等待显示,详见 代码 process.py

自动化爬取要有点节操,所以得加入延时,详见 代码 ziru_room.py

    while(True):
        computedData(usefulIp, userAgent)
        time.sleep(60)

python 一点其他感触,写起来很简洁,这个换行缩进还有dict对象中文Unicode搞了很久。。。目前和node相比优缺点在哪里还没有分析好,可以留言探讨下。

码字辛苦,代码粗糙后续会有优化,点小手star一下谢谢
https://github.com/liangyuqi/...

最后送上彩蛋,这位老哥最后根据github 里qq 找到的我,反反爬虫不算太失败吧,爬取的也不是什么关键数据,手动滑稽,仅供萌新学习练手

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/43116.html

相关文章

  • 虫 - 收藏集 - 掘金

    摘要:在这之前,还是有必要对一些概念超轻量级反爬虫方案后端掘金前言爬虫和反爬虫日益成为每家公司的标配系统。 爬虫修炼之道——从网页中提取结构化数据并保存(以爬取糗百文本板块所有糗事为例) - 后端 - 掘金欢迎大家关注我的专题:爬虫修炼之道 上篇 爬虫修炼之道——编写一个爬取多页面的网络爬虫主要讲解了如何使用python编写一个可以下载多页面的爬虫,如何将相对URL转为绝对URL,如何限速,...

    1fe1se 评论0 收藏0
  • 首次公开,整理12年积累的博客收藏夹,零距离展示《收藏夹吃灰》系列博客

    摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...

    Harriet666 评论0 收藏0
  • SegmentFault 技术周刊 Vol.30 - 学习 Python 来做一些神奇好玩的事情吧

    摘要:学习笔记七数学形态学关注的是图像中的形状,它提供了一些方法用于检测形状和改变形状。学习笔记十一尺度不变特征变换,简称是图像局部特征提取的现代方法基于区域图像块的分析。本文的目的是简明扼要地说明的编码机制,并给出一些建议。 showImg(https://segmentfault.com/img/bVRJbz?w=900&h=385); 前言 开始之前,我们先来看这样一个提问: pyth...

    lifesimple 评论0 收藏0
  • 大话虫的实践技巧

    摘要:图意淫爬虫与反爬虫间的对决数据的重要性如今已然是大数据时代,数据正在驱动着业务开发,驱动着运营手段,有了数据的支撑可以对用户进行用户画像,个性化定制,数据可以指明方案设计和决策优化方向,所以互联网产品的开发都是离不开对数据的收集和分析,数 showImg(https://segmentfault.com/img/remote/1460000013428119?w=539&h=337)...

    沈俭 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<