Python利用requests和xpath爬取网页内容过程

遇到的问题及解决方法

1.xpath()函数的使用-之后会练习使用find_all()函数

需要安装lxml库,xpath()方法放回的结果是一个列表

1.1 XPath 常用规则
表达式描述
nodename1
//从当前节点选取子孙节点
/从当前节点选取子节点
.选取当前结点
选取当前节点的父节点
@选取属性

例子:

//title[@lang='eng']

这是一个 XPath 规则,代表的是选择所有名称为 title,同时属性 class 的值为 eng 的节点,后面会通过 Python 的 lxml 库,利用 XPath 进行 HTML 的解析。

1.2 获取文本
# 第一种
# 获取文本所在节点后直接获取文本
from lxml import etree
html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//li[@class="item-0"]/a/text()')
print(result)

# 第二种
# 会获取到补全代码时换行产生的特殊字符,推荐使用第一种方法,可以保证获取的结果是整洁的。
from lxml import etree
html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//li[@class="item-0"]//text()')
print(result)
1.3 要提取的信息有大量空格

使用normalize-space()函数:

# 提取出来会有大量空格
level = html.xpath('//table[@class="info-tb"]/tr[4]/td[4]/text()')
# 使用normalize-space()
level = html.xpath('normalize-space(//table[@class="info-tb"]/tr[4]/td[4]/text())')
1.4 多属性匹配
# 直接在xpath中使用and
from lxml import etree
result = html.xpath('//li[contains(@class, "li") and @name="item"]/a/text()')
1.5 提取的网址不是完全意义上的网址

只是部分的网址,例如这个网站提取的就是缺少https://dl.58.com的网址,所以要给加上这一块,当提取完后,可以直接这样:

return ['https://dl.58.com' + item for item in list_urls]
1.4 遇到tbody的情况如何处理:

这是网页的规范性问题,可以直接跳过,我们定位路径的时候可以直接忽略这个点

1.5 提取的内容有好多tr,td:

在这里插入图片描述
这个时候我们可以直接定位到某一个点:

# 第三个tr,第四个td
price = html.xpath('normalize-space(//table[@class="info-tb"]/tr[3]/td[4]/text())')

xpath

2. etree.HTML()函数解析

etree.HTML()可以用来解析字符串格式的HTML文档对象,将传进去的字符串转变成_Element对象。作为_Element对象,可以方便的使用getparent()、remove()、xpath()等方法。

url = "https://dl.58.com/xiaoqu/150/"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/87.0.4280.88 Safari/537.36"
}
rep = requests.get(url, headers=headers)
rep.encoding = 'utf-8'
# print(rep.text) 输出的是网页的全部源代码
html = etree.HTML(rep.text) 
# 通过xpath筛选出所需要的代码信息
list_url = html.xpath('//ul[@class="xq-list-wrap"]/li/div[@class="pic"]/a/@href')

3. 保存到Exce:

需要调用xlwt库,同时也需要利用pip安装:pip install xlwt

import xlwt
# 创建一个workbook
workbook = xlwt.Workbook(encoding='utf-8')
# 创建表名
data_sheet = workbook.add_sheet('sheet1')
# 设置表头
row0 = ['1', '2', '3', '4', '5', '6']
# 将第一行写进去
for k in range(0, len(row0)):
    data_sheet.write(0, k, row0[k])
# 利用cnt控制行数
cnt = 1
# 写入全部数据
for item in all_url:
    list_informations = []
    list_informations += get_information(item)
    for j in range(0, len(list_informations)):
        data_sheet.write(cnt, j, list_informations[j])
    cnt += 1
# 保存文件
workbook.save('filename.xlsx')

4. 突然提取不出信息了,返回的是空列表的解决办法

一般这种情况,往往是因为网站觉得你操作太频繁了,需要手动验证一下,这个时候手动打开一个网页,根据网页提示进行操作一个,即可继续进行信息提取。

4.1 注意如果网页操作太频繁的话会被冻结,这个时候可以用time库里面的sleep操作:
# 生成随机数的函数randint
from random import randint
# 设置睡眠时间,即多久运行一次
from time import sleep
# 放到函数里即可,程序执行到这里会进行停顿
sleep(randint(2, 5))

源代码

爬取某同城某地区全部小区信息

from random import randint
import requests
# 直接保存到本地
from lxml import etree
from time import sleep
# 创建excel表格的
import xlwt

def get_name__url():
    list_urls = []
    for i in range(1, 20):
        if i == 1:
            url = "https://dl.58.com/xiaoqu/150/"
        else:
            url = "https://dl.58.com/xiaoqu/150/pn_%d/" % i
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                          "Chrome/87.0.4280.88 Safari/537.36"
        }
        rep = requests.get(url, headers=headers)
        rep.encoding = 'utf-8'
        # print(rep.text)
        html = etree.HTML(rep.text)
        list_url = html.xpath('//ul[@class="xq-list-wrap"]/li/div[@class="pic"]/a/@href')
        list_urls += list_url
    return ['https://dl.58.com' + item for item in list_urls]


def get_information(url):
    # print(url)
    list_information = []
    sleep(randint(2, 5))
    # print(url)
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/87.0.4280.88 Safari/537.36"
    }
    rep = requests.get(url, headers=headers)
    rep.encoding = 'utf-8'
    html = etree.HTML(rep.text)
    name = html.xpath('//div[@class="body-wrapper"]/div[@class="title-bar"]/span/text()')
    # print(name)
    value = html.xpath('//div[@class="body-wrapper"]/div[@class="basic-container"]//div['
                       '@class="price-container"]/span/text()')[:2]
    # all_information = html.xpath('//div[@class="body-wrapper"]/div[@class="basic-container"]/div['
    #                              '@class="info - tb - container"]/table[@class="info-tb"]/tr[5]/td[2]/text()')
    build_year = html.xpath('normalize-space(//table[@class="info-tb"]/tr[5]/td[2]/text())')
    level = html.xpath('normalize-space(//table[@class="info-tb"]/tr[4]/td[4]/text())')
    # print(level)
    nums = html.xpath('normalize-space(//table[@class="info-tb"]/tr[2]/td[4]/text())')
    # print(nums)
    price = html.xpath('normalize-space(//table[@class="info-tb"]/tr[3]/td[4]/text())')
    # print(price)
    list_information += name
    list_information.append(value)
    list_information.append(build_year)
    list_information.append(level)
    list_information.append(nums)
    list_information.append(price)
    print(list_information)
    return list_information

if __name__ == '__main__':
    all_url = get_name__url()
    workbook = xlwt.Workbook(encoding='utf-8')
    # 创建表名
    data_sheet = workbook.add_sheet('小区')
    row0 = ['小区名称', '均价', '建造年代', '容积率', '户数', '物业费']
    for k in range(0, len(row0)):
        data_sheet.write(0, k, row0[k])
    cnt = 1
    for item in all_url:
    	# 看看执行到多少条了
        print(cnt)
        list_informations = []
        list_informations += get_information(item)
        for j in range(0, len(list_informations)):
            data_sheet.write(cnt, j, list_informations[j])
        cnt += 1
    workbook.save('沙口区小区信息.xlsx')
    print("程序执行完成")
  • 33
    点赞
  • 137
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JdiLfc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值