python解析网页获取的数据如何去掉其中的空行ValueError: arrays must all be same length

今天做了一个python的一个比较小的实战案例:基于链家网二手房数据解析网页并从中获取如下信息:

  1. 标题
  2. 位置
  3. 房屋信息
  4. 关注人数 / 发布时间
  5. 房屋总价
  6. 房屋单价
  7. 备注信息

最后调用函数的时候报错ValueError: arrays must all be same length
如下面的两张图:
python解析网页获取的数据如何去掉其中的空行ValueError: arrays must all be same length_第1张图片
python解析网页获取的数据如何去掉其中的空行ValueError: arrays must all be same length_第2张图片
原来查看了一下他们的数据长度,发现有的数据长度为30,有的数据长度为60,如下图所示:
python解析网页获取的数据如何去掉其中的空行ValueError: arrays must all be same length_第3张图片
查看其中60的数据中,发现是空格和空行占据了1/2,如下图所示:
python解析网页获取的数据如何去掉其中的空行ValueError: arrays must all be same length_第4张图片
初步解决消除空格和空行的两种方法:

#写法一: 
#house_info_2 = [] 
#for i in house_info: 
#    house_info_2.append(re.sub('\s', '', i)) 
#写成如下形式:
house_info = html.xpath('//div[@class="info clear"]//div[@class="houseInfo"]/text()').extract() 
for i in house_info: 
    house_info.append(re.sub('\s', '', i))

#写法二:
#house_info_2 = [re.sub('\s', '', i) for i in house_info] 
#写成如下形式:
house_info1 = html.xpath('//div[@class="info clear"]//div[@class="houseInfo"]/text()').extract() 
house_info = [re.sub('\s', '', i) for i in house_info1] 
house_info

这种方法虽然把空格去掉了,但是有单引号单独占有的空行,长度仍为60,而其他数据的获取长度均为30
如下图所示:
python解析网页获取的数据如何去掉其中的空行ValueError: arrays must all be same length_第5张图片
再次进行修改:

#第一种——获取房屋信息
house_info = [re.sub('\s', '', i) for i in html.xpath('//li[@class="clear"]//div[@class="houseInfo"]/text()[2]').extract()]
print(len(house_info))

#第二种——获取房屋信息
house_info = [re.search(r'houseIcon">(.*?)
', i, re.S).group(1) for i in html.xpath('//li[@class="clear"]//div[@class="houseInfo"]').extract()] house_info_2 = [re.sub('\s', '', i) for i in house_info] print(len(house_info_2))

结果如下:
python解析网页获取的数据如何去掉其中的空行ValueError: arrays must all be same length_第6张图片
python解析网页获取的数据如何去掉其中的空行ValueError: arrays must all be same length_第7张图片
这样就解决问题啦!!!
好啦,接下来记录一下我所写的所有的代码吧!!!

完整的代码如下:

#导入库
import pandas as pd 
import requests
import parsel
import re                    #使用正则表达式时要用到的库
import time
#获取URL
url = 'https://bd.ke.com/ershoufang/'

#添加headers
headers = {
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}

#发起请求
r = requests.get(url, headers=headers)
print(r.text)

#解析网页
html = parsel.Selector(r.text)    #将其实例化成一个r.text,Selector对象为html
#获取标题
title = html.xpath('//div[@class="info clear"]/div[@class="title"]/a/text()').extract() 
print(len(title))

#获取位置
position = html.xpath('//div[@class="info clear"]//div[@class="positionInfo"]//a/text()').extract()
print(len(position))

#第一种——获取房屋信息
house_info = [re.sub('\s', '', i) for i in html.xpath('//li[@class="clear"]//div[@class="houseInfo"]/text()[2]').extract()]
print(len(house_info))

#第二种——获取房屋信息
house_info = [re.search(r'houseIcon">(.*?)
', i, re.S).group(1) for i in html.xpath('//li[@class="clear"]//div[@class="houseInfo"]').extract()] house_info_2 = [re.sub('\s', '', i) for i in house_info] print(len(house_info_2)) # 关注信息 follow_info = [re.sub('\s', '', i) for i in html.xpath('//li[@class="clear"]//div[@class="followInfo"]/text()[2]').extract()] print(len(title)) #获取房屋总价 #由于房价是由span标签和其下面的文本内容组成的,有两种方式 #第一种——将数字和单位万进行拼接 total_price = [i+'万' for i in html.xpath('//div[@class="info clear"]//div[@class="totalPrice"]/span/text()').extract()] print(len(total_price)) #第二种——使用正则表达式 #'.'点表示匹配任意字符 #'*'星表示匹配零次或多次 #'?'问号表示非贪婪模式 total_price = [''.join(re.findall(r'(.*?)(.*?)
', i)[0]) for i in html.xpath('//div[@class="info clear"]//div[@class="totalPrice"]').extract()] print(len(total_price)) #获取房屋单价 unit_price = html.xpath('//div[@class="info clear"]//div[@class="unitPrice"]/span/text()').extract() print(len(unit_price)) # 获取备注信息 tag_info = [' | '.join(re.findall(r'[\u4e00-\u9fa5]+', i)) for i in html.xpath('//div[@class="info clear"]//div[@class="tag"]').extract()] print(len(tag_info))
# 将上述过程封装成函数
def get_lianjia_one_page(url):
    """功能:给定链家网二手房地址,获取一页的信息"""
    #添加headers
    headers = {
        'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
    }

    #发起请求
    r = requests.get(url, headers=headers)
    
    # 解析网页
    html = parsel.Selector(r.text)

    # 获取信息
    title = html.xpath('//div[@class="info clear"]/div[@class="title"]/a/text()').extract()
    position = html.xpath('//div[@class="info clear"]//div[@class="positionInfo"]//a/text()').extract()
    house_info = [re.sub('\s', '', i) for i in html.xpath('//li[@class="clear"]//div[@class="houseInfo"]/text()[2]').extract()]    
    follow_info = [re.sub('\s', '', i) for i in html.xpath('//li[@class="clear"]//div[@class="followInfo"]/text()[2]').extract()]
    total_price = [''.join(re.findall(r'(.*?)(.*?)
', i)[0]) for i in html.xpath('//div[@class="info clear"]//div[@class="totalPrice"]').extract()] unit_price = html.xpath('//div[@class="info clear"]//div[@class="unitPrice"]/span/text()').extract() tag_info = [' | '.join(re.findall(r'[\u4e00-\u9fa5]+', i)) for i in html.xpath('//div[@class="info clear"]//div[@class="tag"]').extract()] # 保存信息 df_one = pd.DataFrame({ 'title': title, 'position': position, 'house_info': house_info, 'follow_info': follow_info, 'total_price': total_price, 'unit_price': unit_price, 'tag_info': tag_info }) return df_one # 获取URL url = 'https://bd.ke.com/ershoufang/' # 调用上面的函数 df_one = get_lianjia_one_page(url) df_one.head()

得到的结果如下:
python解析网页获取的数据如何去掉其中的空行ValueError: arrays must all be same length_第8张图片
但这样子的__得到的是一页的数据__,现在要得到多页数据

# 多页面
def get_lianjia_100_page(city_name):
    """
    功能:给定城市名,获取100页的信息
    """    
    df_all = pd.DataFrame()
    # 构建URL地址
    for page_num in range(100): 
        try:
            url = 'https://{}.ke.com/ershoufang/pg{}/'.format(city_name, page_num+1) 
            # 调用函数
            df_one = get_lianjia_one_page(url) 
            # 循环追加
            df_all = df_all.append(df_one, ignore_index=True)
            # 打印进度
            print('我正在获取第{}页的信息'.format(page_num+1), end='\r')
            # 休眠一秒
            time.sleep(1) 
        except Exception as e:
            break
    return df_all

#调用函数
df_all = get_lianjia_100_page(city_name='bd')  

你可能感兴趣的:(Python)