zoukankan      html  css  js  c++  java
  • python3通过Beautif和XPath分别爬取“小猪短租-北京”租房信息,并对比时间效率(附源代码)

    爬虫思路分析:

    1. 观察小猪短租(北京)的网页

    首页:http://www.xiaozhu.com/?utm_source=baidu&utm_medium=cpc&utm_term=PC%E6%A0%87%E9%A2%98&utm_content=pinzhuan&utm_campaign=BDPZ

    选择“北京”,然后点“搜索小猪”,获取北京市的首页url:http://bj.xiaozhu.com/

    观察右侧详情,页面最下面有分页,点击第2、第3页观察url的变化

    http://bj.xiaozhu.com/search-duanzufang-p2-0/

    http://bj.xiaozhu.com/search-duanzufang-p3-0/

    验证首页是否可以写作:http://bj.xiaozhu.com/search-duanzufang-p1-0/(答案是ok的,大部分分页行的网站首页都是可以与其他分页统一化的)

    因此,分页的URL可以这么构造:http://bj.xiaozhu.com/search-duanzufang-p{}-0/.format(number),其中number是几就是第几页

    2. 观察右侧的信息,发现每个房源的信息不全,需要手动点击进去才能看到详情

    因此需要获取每个房源的详情页面的URL

    3. 观察某一房源的详细信息,这里我们提取“标题、地址、价格、房东名字、性别”等

    使用BeautifulSoup实现

     1 """
     2 典型的分页型网站——小猪短租
     3 使用Beautifulsoup解析网页,并对比时间效率
     4 
     5 """
     6 
     7 import requests
     8 from bs4 import BeautifulSoup as bs
     9 import time
    10 
    11 headers = {
    12     'User-Agent':'User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
    13 }
    14 
    15 #--Beautifulsoup--
    16 
    17 """获取每一个房源的网址,参数是分页url"""
    18 def get_link(url):
    19     html_data = requests.get(url, headers = headers)
    20     soup = bs(html_data.text, 'lxml')#bs4推荐使用的的解析库
    21     #print(soup.prettify())   #标准化输出url中的源代码(有可能跟网页查看中的不一致,网页中有可能标签书写不规范)以此为基础抓取,如果抓取失败,用此命令查看源代码
    22     links = soup.select('#page_list > ul > li > a')#注意循环点!!!直接粘贴过来的是“#page_list > ul > li:nth-child(1) > a > img”,需要去掉:nth-child(1),注意每个标签前后有空格
    23     #print(links)
    24     for link in links:
    25         link = link.get('href')
    26         #print(link)
    27         get_info(link)
    28 
    29 """判断房东性别"""
    30 def sex_is(member):
    31     if member == 'member_ico':
    32         return ""
    33     else:
    34         return ""
    35 
    36 """获取每一个房源的详细信息,参数url是每个房源的网址"""
    37 def get_info(url):
    38     html_data = requests.get(url, headers = headers)
    39     soup = bs(html_data.text, 'lxml')#bs4推荐使用的的解析库
    40     # print(soup.prettify())   #标准化输出url中的源代码(有可能跟网页查看中的不一致,网页中有可能标签书写不规范)以此为基础抓取,如果抓取失败,用此命令查看源代码
    41     title = soup.select('div.wrap.clearfix.con_bg > div.con_l > div.pho_info > h4 > em')[0].string
    42     # 用网页copy过来的全部是“body > div.wrap.clearfix.con_bg > div.con_l > div.pho_info > h4 > em”,但是使用这个爬不出来数据(我也不知道why),把body去掉或者用下面最简短的方式(只使用最近的且唯一的div)
    43     # title = soup.select('div.pho_info > h4 > em ')
    44     # 查询结果title格式是一维列表,需要继续提取列表元素(一般就是[0]),列表元素是前后有标签需要继续提取标签内容,使用get_text()或者string
    45 
    46     address = soup.select('div.wrap.clearfix.con_bg > div.con_l > div.pho_info > p > span')[0].string.strip()
    47     price = soup.select('#pricePart > div.day_l > span')[0].string.strip()  # div中的id=pricePart是唯一性的,因此不用写前面的div
    48     name = soup.select('#floatRightBox > div.js_box.clearfix > div.w_240 > h6 > a')[0].string.strip()
    49     img = soup.select('#floatRightBox > div.js_box.clearfix > div.member_pic > a > img')[0].get('src').strip()  # 获取标签的属性值
    50     sex = sex_is(soup.select('#floatRightBox > div.js_box.clearfix > div.member_pic > div')[0].get('class')[0].strip())  # 获取标签的属性值
    51 
    52     #将详细数据整理成字典格式
    53     data = {
    54         '标题':title,
    55         '地址':address,
    56         '价格':price,
    57         '房东姓名':name,
    58         '房东性别':sex,
    59         '房东头像':img
    60     }
    61     print(data)
    62 
    63 
    64 """程序主入口"""
    65 if __name__=='__main__':
    66     start = time.time()
    67     for number in range(1,4):
    68         url = 'http://bj.xiaozhu.com/search-duanzufang-p{}-0/'.format(number)   #构造分页url(不是房源详情的url)
    69         get_link(url)
    70         time.sleep(5)
    71     end = time.time()
    72     print('运行时长:',end-start)

    使用Xpath实现

     1 """
     2 典型的分页型网站——小猪短租
     3 使用Xpath解析网页,并对比时间效率
     4 """
     5 
     6 import requests
     7 from lxml import etree
     8 import time
     9 
    10 headers = {
    11     'User-Agent':'User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
    12 }
    13 
    14 #--Xpath--
    15 
    16 """获取每一个房源的网址,参数是分页url"""
    17 def get_link(url):
    18     html_data = requests.get(url, headers=headers)
    19     selector = etree.HTML(html_data.text)
    20     infos = selector.xpath('//*[@id="page_list"]/ul/li')
    21     for info in infos:
    22         link = info.xpath('a[1]/@href')[0].strip()#获取a标签中的href使用@,注意写法
    23         #link = link.get('href')
    24         #print(link)
    25         get_info(link)
    26 
    27 """判断房东性别"""
    28 def sex_is(member):
    29     if member == 'member_ico':
    30         return ""
    31     else:
    32         return ""
    33 
    34 """#获取每一个房源的详细信息,参数url是每个房源的网址"""
    35 def get_info(url):
    36     html_data = requests.get(url, headers=headers)
    37     selector = etree.HTML(html_data.text)
    38     # title = selector.xpath('//div[3]/div[1]/div[1]/h4/em')#直接使用copyxpath的结果为空,原因未知,address字段同样情况
    39     title = selector.xpath('//div[@class="wrap clearfix con_bg"]/div[1]/div[1]/h4/em/text()')[0].strip()
    40     # title = selector.xpath('//div[@class="pho_info"]/h4/em/text()')[0].strip()
    41     address = selector.xpath('//div[@class="pho_info"]/p/span/text()')[0].strip()
    42     price = selector.xpath('//*[@id="pricePart"]/div[1]/span/text()')[0].strip()
    43     #name = selector.xpath('//*[@id="floatRightBox"]/div[3]/div[2]/h6/a/@title')[0].strip()#此段是直接copy xpath的,某些房源会报错,因为有些房东认证了“超棒房东”,会多一行div
    44     name = selector.xpath('//*[@id="floatRightBox"]/div[3]/div[@class="w_240"]/h6/a/@title')[0].strip()
    45     #img = selector.xpath('//*[@id="floatRightBox"]/div[3]/div[1]/a/img/@src')[0].strip()#原因同name
    46     img = selector.xpath('//*[@id="floatRightBox"]/div[3]/div[@class="member_pic"]/a/img/@src')[0].strip()
    47 
    48     sex = sex_is(selector.xpath('//*[@id="floatRightBox"]/div[3]/div[1]/div/@class')[0].strip())
    49     #将详细数据整理成字典格式
    50     data = {
    51         '标题':title,
    52         '地址':address,
    53         '价格':price,
    54         '房东姓名':name,
    55         '房东性别':sex,
    56         '房东头像':img
    57     }
    58     print(data)
    59 
    60 
    61 """程序主入口"""
    62 if __name__=='__main__':
    63     start = time.time()
    64     for number in range(1,4):
    65         url = 'http://bj.xiaozhu.com/search-duanzufang-p{}-0/'.format(number)   #构造分页url(不是房源详情的url)
    66         get_link(url)
    67         time.sleep(5)
    68     end = time.time()
    69     print('运行时长:',end-start)

    对比时间效率

    爬取1-3页数据,每页延时5s

    BeautifulSoup用时27.9475s

    XPath用时24.0693s

    综上所述

    XPath用时更短一些,并且XPath写法更简洁。对比而言,更推荐使用XPath进行网页解析。

    值得注意的是,copy XPath的方法虽然好用,但是某些情况有可能抓取失败,比如本例中的title、name和img,此时需要手写(可以尝试明确class和id的写法提高抓取效率)

  • 相关阅读:
    Android 四大组件 (二) Service 使用
    使用fiddler抓手机端http数据包
    解决问题:保存图片到本地文件夹后,在图库里看不到保存的图片问题。
    Android 四大组件 (一) Activity 生命周期
    第二次裸辞_潜伏期_一些感想
    最近的一些感想(关于移动客户端开发android,ios)
    错误:类型 'System.Object' 未定义或者不能引入项目
    easyui换主题,并记录在cookie.以及cookie作用域介绍
    VS发布报错 "未能将文件……复制到……"
    VS2013修改模板,增加类文件的头注释
  • 原文地址:https://www.cnblogs.com/aby321/p/9946831.html
Copyright © 2011-2022 走看看