前言:

苦逼的我从某某城市换到另一个稍微大点的某某城市,面临的第一个问题就是买房,奋斗10多年,又回到起点,废话就不多说了,看看如何设计程序把某同城上的房价数据抓取过来。

方案:方案思路很简单,先把网页内容获取下来,通过一定规则对内容解析,保存成想要的格式

难点是对网页的解析,是一个比较细致的活,必须边输出,边调试。

具体实现:

获取网页内容:

def get_page(url):
    headers = {
        'User-Agent': r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      r'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3',
        'Referer': r'http://jn.58.com/ershoufang/',
        'Host': r'jn.58.com',
        'Connection': 'keep-alive'
    }
    timeout = 60
    socket.setdefaulttimeout(timeout)  # 设置超时
    req = request.Request(url, headers=headers)
    response = request.urlopen(req).read()
    page = response.decode('utf-8','ignore')
    return page

第二步解析网页:解析时要注意无效内容的处理,不然跑起来会报错,调试很麻烦

def get_58_house(url):   
    html = get_page(url)
    soup =  BeautifulSoup(html,"lxml")
    table =soup.find(id="main")
    df = pd.DataFrame(columns=["op_time","web","house_name","xq","xq1","price","per_price","room","m2","href","ts"])
    for tr in table.find_all('tr'):
        try:
            str_name = tr.find("p","bthead").find("a","t").string.strip()
            str_link = tr.find("p","bthead").find("a","t")["href"]

##房产小区位置
            str_xq = list()  
            str_xq1= ''
            str_xq2= ''
            try:
                for s in tr.find_all("a","a_xq1")    :
                    str_xq.append(s.string.strip()) 
                str_xq1= str_xq[0]
                str_xq2= str_xq[1]
            except:
                pass
            ##房产特色
            str_ts =list()
            try:
                for s in tr.find("div","qj-listleft").stripped_strings:
                    str_ts.append(s)
            except:
                pass

## 价格信息####################
            str_price =list()
            str_toal =''
            str_per =''
            str_room =''
            str_m2 =''
            try:
                for s in tr.find("div","qj-listright btall").stripped_strings:
                    str_price.append(s)
                str_toal = str_price[0]
                str_per  = re.findall(r"(\d+\.*\d+)",str_price[1])
                str_room = str_price[2]
                str_m2  = re.findall(r"(\d+\.*\d+)",str_price[3])           
            except:
                pass
        except Exception as e:
            print('Exception',":",e)
                       
        try: 
            row = {'web':'58同城','house_name':str_name,'xq':str_xq1,'xq1':str_xq2,'price':str_toal,'per_price':str_per,'room':str_room,'m2':str_m2,'ts':''.join(str_ts),'href':str_link}
            newrow = pd.DataFrame(data=row,index=["0"])
            df=df.append(newrow,ignore_index=True)
        except Exception as e:
            print('Exception',":",e)
            f=open("log.txt",'a')
            traceback.print_exc(file=f) 
            f.write(row) 
            f.flush() 
            f.close()
    df["op_time"]=time.strftime('%Y-%m-%d',time.localtime(time.time()))
    return df

第三步循环处理每页数据并保存数据:

def get_58_house_all():
    ##建立数据库连接
    engine = create_engine('oracle+cx_oracle://user:password@localhost/orcl')
    cnx = engine.connect() 
    ##先清除今天的数据
    '''
    strSql = 'delete from house where op_time=\'{}\' '.format(time.strftime('%Y-%m-%d',time.localtime(time.time())))
    cnx.execute(strSql)
    '''
    ##获取首页房产数据   
    str_http = "http://jn.58.com/ershoufang/"
   
    writelog(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' Start:'+str_http)
       
    df1=get_58_house(str_http)
    try:
        df1.to_sql('house', cnx,if_exists='append')
    except Exception as e:
        '''记录异常信息
                    本例使用的是oracle 数据库,默认编码格式为GBK,保存时因为特殊字符,导致保存错误。错误提示如下,需要调整oracle字符集
         oracle 字符集调整为UTF8,
         NLS_LANG: AMERICAN_AMERICA.AL32UTF8
         NLS_CHARACTERSET: UTF8
         NLS_NCHAR_CHARACTERSET: UTF8
                   报错信息为
         UnicodeEncodeError: 'gbk' codec can't encode character '\xb2' in position 13: illegal multibyte sequence
                     该字符为上标2,平方米          
        '''
        writelog(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' Except:'+str_http)
       
        df1.to_csv('record.csv',sep=',', encoding='utf-8')
        writelog(traceback.format_exc())
       
    writelog(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' End:'+str_http)
    time.sleep(20)
 
    ##获取其余69页房产数据
    for i in range(2,70+1) :
        try:
            str_http ="http://jn.58.com/ershoufang/pn"+str(i)
            writelog(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' Start:'+str_http)
           
            df1=get_58_house(str_http)       
            df1.to_sql('house', cnx,if_exists='append')
        except Exception as e:
            ##writelog(''.format('Save to database Exception',":",e)  )
            writelog(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' Except:'+str_http)
           
            df1.to_csv('record.csv',sep=',', encoding='utf-8')
            writelog(traceback.format_exc())
           
        writelog(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' End:'+str_http)
        time.sleep(20)

##关闭数据链接
    cnx.close()

跑跑看看是不是程序一切运行正常。

Python开发网络爬虫抓取某同城房价信息的更多相关文章

  1. 如何利用Python网络爬虫抓取微信朋友圈的动态(上)

    今天小编给大家分享一下如何利用Python网络爬虫抓取微信朋友圈的动态信息,实际上如果单独的去爬取朋友圈的话,难度会非常大,因为微信没有提供向网易云音乐这样的API接口,所以很容易找不到门.不过不要慌 ...

  2. 利用Python网络爬虫抓取微信好友的签名及其可视化展示

    前几天给大家分享了如何利用Python词云和wordart可视化工具对朋友圈数据进行可视化,利用Python网络爬虫抓取微信好友数量以及微信好友的男女比例,以及利用Python网络爬虫抓取微信好友的所 ...

  3. 利用Python网络爬虫抓取微信好友的所在省位和城市分布及其可视化

    前几天给大家分享了如何利用Python网络爬虫抓取微信好友数量以及微信好友的男女比例,感兴趣的小伙伴可以点击链接进行查看.今天小编给大家介绍如何利用Python网络爬虫抓取微信好友的省位和城市,并且将 ...

  4. 如何利用Python网络爬虫抓取微信好友数量以及微信好友的男女比例

    前几天给大家分享了利用Python网络爬虫抓取微信朋友圈的动态(上)和利用Python网络爬虫爬取微信朋友圈动态——附代码(下),并且对抓取到的数据进行了Python词云和wordart可视化,感兴趣 ...

  5. 基于Thinkphp5+phpQuery 网络爬虫抓取数据接口,统一输出接口数据api

    TP5_Splider 一个基于Thinkphp5+phpQuery 网络爬虫抓取数据接口 统一输出接口数据api.适合正在学习Vue,AngularJs框架学习 开发demo,需要接口并保证接口不跨 ...

  6. PID控制器的应用:控制网络爬虫抓取速度

    一.初识PID控制器 冬天乡下人喜欢烤火取暖,常见的情形就是四人围着麻将桌,桌底放一盆碳火.有人觉得火不够大,那加点木炭吧,还不够,再加点.片刻之后,又觉得火太大,脚都快被烤熟了,那就取出一些木碳…… ...

  7. python网络爬虫抓取动态网页并将数据存入数据库MySQL

    简述以下的代码是使用python实现的网络爬虫,抓取动态网页 http://hb.qq.com/baoliao/ .此网页中的最新.精华下面的内容是由JavaScript动态生成的.审查网页元素与网页 ...

  8. [Python学习] 简单网络爬虫抓取博客文章及思想介绍

            前面一直强调Python运用到网络爬虫方面很有效,这篇文章也是结合学习的Python视频知识及我研究生数据挖掘方向的知识.从而简介下Python是怎样爬去网络数据的,文章知识很easy ...

  9. 使用Python编写简单网络爬虫抓取视频下载资源

    我第一次接触爬虫这东西是在今年的5月份,当时写了一个博客搜索引擎.所用到的爬虫也挺智能的,起码比电影来了这个站用到的爬虫水平高多了! 回到用Python写爬虫的话题. Python一直是我主要使用的脚 ...

随机推荐

  1. 最适合初学者学习的idea教程

    https://github.com/judasn/IntelliJ-IDEA-Tutorial

  2. SPOJ 1182 Sorted bit sequence

    题目链接 题意: 分析: 其实如果会了Ural 1057. Amount of Degrees那道题目,这道题自然也就会了... 我们考虑枚举第$k$个数字的$1$的个数,那么我们需要计算的也就是区间 ...

  3. 【HDU5785】Interesting [Manacher]

    Interesting Time Limit: 30 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description Input Outp ...

  4. BestCoder Round #39 解题报告

    现场只做出前三题w 不过不管怎样这既是第一次认真打BC 又是第一次体验用在线编译器调代码 订正最后一题花了今天一整个下午(呜呜 收获还是比较大的^_^ Delete wld有n个数(a1,a2,... ...

  5. celery后台运行

    参考:https://blog.csdn.net/qq_18863573/article/details/52437689 pip install supervisor # 要用python2的pip ...

  6. XGBOOST/GBDT,RandomForest/Bagging的比较

    原创文章:http://blog.csdn.net/qccc_dm/article/details/63684453 首先XGBOOST,GBDT,RF都是集成算法,RF是Bagging的变体,与Ba ...

  7. Selenium2+python自动化42-判断元素(expected_conditions)【转载】

    前言 经常有小伙伴问,如何判断一个元素是否存在,如何判断alert弹窗出来了,如何判断动态的元素等等一系列的判断,在selenium的expected_conditions模块收集了一系列的场景判断方 ...

  8. docker从零开始(五)堆栈初体验,stacks

    先决条件 安装Docker 1.13或更高版本. 获取Docker Compose,请参考第三节 按照第四节中的描述获取Docker Machine. 在第二节中了解如何创建容器. 确保您的图像作为已 ...

  9. 使用JQuery解析、处理JSON数据(应用在课程表)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. ajax按钮改变数据状态

    1.html代码 <td> @if($project->done_deal==) <button type="button" class="btn ...