Python爬虫项目--爬取自如网房源信息

本次爬取自如网房源信息所用到的知识点:

1. requests get请求

2. lxml解析html

3. Xpath

4. MongoDB存储

正文

1.分析目标站点

1. url: http://hz.ziroom.com/z/nl/z3.html?p=2 的p参数控制分页

2. get请求

2.获取单页源码

 1 # -*- coding: utf-8 -*-
 2 import requests
 3 import time
 4 from requests.exceptions import RequestException
 5 def get_one_page(page):
 6     try:
 7         url = "http://hz.ziroom.com/z/nl/z2.html?p=" + str(page)
 8         headers = {
 9             ‘Referer‘:‘http://hz.ziroom.com/‘,
10             ‘Upgrade-Insecure-Requests‘:‘1‘,
11             ‘User-Agent‘:‘Mozilla/5.0(WindowsNT6.3;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/68.0.3440.106Safari/537.36‘
12         }
13         res = requests.get(url,headers=headers)
14         if res.status_code == 200:
15             print(res.text)
16     except RequestException:
17         return None
18 def main():
19     page = 1
20     get_one_page(page)
21 if __name__ == ‘__main__‘:
22     main()
23     time.sleep(1)

3.解析单页源码

1. 解析html文档, 目的: 测试XPath表达式

将获取的源码保存到当前文件夹下的"result.html"中, 然后通过XPath对其进行相应内容的提取, 当然你也可以使用某些在线工具.

 1 from lxml import etree
 2 #解析html文档
 3 html = etree.parse("./resul.html",etree.HTMLParser())
 4 results = html.xpath(‘//ul[@id="houseList"]/li‘)
 5 for result in results[1:]:
 6     title = result.xpath("./div/h3/a/text()")[0][5:] if len(result.xpath("./div/h3/a/text()")[0]) >5 else ""
 7     location = result.xpath("./div/h4/a/text()")[0].replace("[","").replace("]",‘‘)
 8     area = " ".join(result.xpath("./div/div/p[1]/span/text()")).replace(" ","",1) #使用join方法将列表中的内容以" "字符连接
 9     nearby = result.xpath("./div/div/p[2]/span/text()")[0]
10     print(title)
11     print(location)
12     print(area)
13     print(nearby)

2. 解析源代码

 1 from lxml import etree
 2 def parse_one_page(sourcehtml):
 3     ‘‘‘解析单页源码‘‘‘
 4     contentTree = etree.HTML(sourcehtml)   #解析源代码
 5     results = contentTree.xpath(‘//ul[@id="houseList"]/li‘) #利用XPath提取相应内容
 6     for result in results[1:]:
 7         title = result.xpath("./div/h3/a/text()")[0][5:] if len(result.xpath("./div/h3/a/text()")[0]) > 5 else ""
 8         location = result.xpath("./div/h4/a/text()")[0].replace("[", "").replace("]", ‘‘)
 9         area = " ".join(result.xpath("./div/div/p[1]/span/text()")).replace(" ", "", 1)  # 使用join方法将列表中的内容以" "字符连接
10         nearby = result.xpath("./div/div/p[2]/span/text()")[0]
11         yield {
12         "title": title,
13         "location": location,
14         "area": area,
15         "nearby": nearby
16         }
17 def main():
18     page = 1
19     html = get_one_page(page)
20     print(type(html))
21     parse_one_page(html)
22     for item in parse_one_page(html):
23       print(item)
24
25 if __name__ == ‘__main__‘:
26     main()
27     time.sleep(1)

4.获取多个页面

 1 def parse_one_page(sourcehtml):
 2     ‘‘‘解析单页源码‘‘‘
 3     contentTree = etree.HTML(sourcehtml)   #解析源代码
 4     results = contentTree.xpath(‘//ul[@id="houseList"]/li‘) #利用XPath提取相应内容
 5     for result in results[1:]:
 6         title = result.xpath("./div/h3/a/text()")[0][5:] if len(result.xpath("./div/h3/a/text()")[0]) > 5 else ""
 7         location = result.xpath("./div/h4/a/text()")[0].replace("[", "").replace("]", ‘‘)
 8         area = " ".join(result.xpath("./div/div/p[1]/span/text()")).replace(" ", "", 1)  # 使用join方法将列表中的内容以" "字符连接
 9         #nearby = result.xpath("./div/div/p[2]/span/text()")[0].strip()这里需要加判断, 改写为下句
10         nearby = result.xpath("./div/div/p[2]/span/text()")[0].strip() if len(result.xpath("./div/div/p[2]/span/text()"))>0 else ""
11         yield {
12         "title": title,
13         "location": location,
14         "area": area,
15         "nearby": nearby
16         }
17         print(nearby)
18     #yield {"pages":pages}
19 def get_pages():
20     """得到总页数"""
21     page = 1
22     html = get_one_page(page)
23     contentTree = etree.HTML(html)
24     pages = int(contentTree.xpath(‘//div[@class="pages"]/span[2]/text()‘)[0].strip("共页"))
25     return pages
26 def main():
27     pages = get_pages()
28     print(pages)
29     for page in range(1,pages+1):
30         html = get_one_page(page)
31         for item in parse_one_page(html):
32             print(item)
33
34 if __name__ == ‘__main__‘:
35     main()
36     time.sleep(1)

5. 存储到MongoDB中

需确保MongoDB已启动服务, 否则必然会存储失败

 1 def save_to_mongodb(result):
 2     """存储到MongoDB中"""
 3     # 创建数据库连接对象, 即连接到本地
 4     client = pymongo.MongoClient(host="localhost")
 5     # 指定数据库,这里指定ziroom
 6     db = client.iroomz
 7     # 指定表的名称, 这里指定roominfo
 8     db_table = db.roominfo
 9     try:
10         #存储到数据库
11         if db_table.insert(result):
12             print("---存储到数据库成功---",result)
13     except Exception:
14         print("---存储到数据库失败---",result)

6.完整代码

 1 # -*- coding: utf-8 -*-
 2
 3 import requests
 4 import time
 5 import pymongo
 6 from lxml import etree
 7 from requests.exceptions import RequestException
 8 def get_one_page(page):
 9     ‘‘‘获取单页源码‘‘‘
10     try:
11         url = "http://hz.ziroom.com/z/nl/z2.html?p=" + str(page)
12         headers = {
13             ‘Referer‘:‘http://hz.ziroom.com/‘,
14             ‘Upgrade-Insecure-Requests‘:‘1‘,
15             ‘User-Agent‘:‘Mozilla/5.0(WindowsNT6.3;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/68.0.3440.106Safari/537.36‘
16         }
17         res = requests.get(url,headers=headers)
18         if res.status_code == 200:
19             return res.text
20         return None
21     except RequestException:
22         return None
23 def parse_one_page(sourcehtml):
24     ‘‘‘解析单页源码‘‘‘
25     contentTree = etree.HTML(sourcehtml)   #解析源代码
26     results = contentTree.xpath(‘//ul[@id="houseList"]/li‘) #利用XPath提取相应内容
27     for result in results[1:]:
28         title = result.xpath("./div/h3/a/text()")[0][5:] if len(result.xpath("./div/h3/a/text()")[0]) > 5 else ""
29         location = result.xpath("./div/h4/a/text()")[0].replace("[", "").replace("]", ‘‘)
30         area = " ".join(result.xpath("./div/div/p[1]/span/text()")).replace(" ", "", 1)  # 使用join方法将列表中的内容以" "字符连接
31         #nearby = result.xpath("./div/div/p[2]/span/text()")[0].strip()这里需要加判断, 改写为下句
32         nearby = result.xpath("./div/div/p[2]/span/text()")[0].strip() if len(result.xpath("./div/div/p[2]/span/text()"))>0 else ""
33         data = {
34         "title": title,
35         "location": location,
36         "area": area,
37         "nearby": nearby
38         }
39         save_to_mongodb(data)
40     #yield {"pages":pages}
41 def get_pages():
42     """得到总页数"""
43     page = 1
44     html = get_one_page(page)
45     contentTree = etree.HTML(html)
46     pages = int(contentTree.xpath(‘//div[@class="pages"]/span[2]/text()‘)[0].strip("共页"))
47     return pages
48 def save_to_mongodb(result):
49     """存储到MongoDB中"""
50     # 创建数据库连接对象, 即连接到本地
51     client = pymongo.MongoClient(host="localhost")
52     # 指定数据库,这里指定ziroom
53     db = client.iroomz
54     # 指定表的名称, 这里指定roominfo
55     db_table = db.roominfo
56     try:
57         #存储到数据库
58         if db_table.insert(result):
59             print("---存储到数据库成功---",result)
60     except Exception:
61         print("---存储到数据库失败---",result)
62
63 def main():
64     pages = get_pages()
65     print(pages)
66     for page in range(1,pages+1):
67         html = get_one_page(page)
68         parse_one_page(html)
69
70 if __name__ == ‘__main__‘:
71     main()
72     time.sleep(1)

点击查看

7.最终结果

总结

1. 在第三步中XPath使用注意事项

title = result.xpath("./div/h3/a/text()")
此处的点‘.‘不能忘记, 它表示当前节点, 如果不加‘.‘, ‘/‘就表示从根节点开始选取

2. 在第四步获取多个页面时出现索引超出范围错误

nearby = result.xpath("./div/div/p[2]/span/text()")[0].strip()

IndexError: list index out of range

造成这种错误原因有两种:

1) [index] index超出list范围

2) [index] index索引内容为空

因为这里的nearby的index是0, 排除第一种情况, 那么这里就是空行了, 加句if判断就可以解决

nearby = result.xpath("./div/div/p[2]/span/text()")[0].strip()
#改写以后:
nearby = result.xpath("./div/div/p[2]/span/text()")[0].strip() if len(result.xpath("./div/div/p[2]/span/text()"))>0 else ""

以上主要是对爬虫过程学习的总结, 若有不对的地方, 还请指正, 谢谢!

因还在学习中, 价格部分会用到图片识别, 有待完善.

原文地址:https://www.cnblogs.com/star-zhao/p/9637588.html

时间: 2024-10-11 06:08:37

Python爬虫项目--爬取自如网房源信息的相关文章

[Python爬虫] Selenium爬取新浪微博客户端用户信息、热点话题及评论 (上)

一. 文章介绍 前一篇文章"[python爬虫] Selenium爬取新浪微博内容及用户信息"简单讲述了如何爬取新浪微博手机端用户信息和微博信息. 用户信息:包括用户ID.用户名.微博数.粉丝数.关注数等. 微博信息:包括转发或原创.点赞数.转发数.评论数.发布时间.微博内容等. 它主要通过从文本txt中读取用户id,通过"URL+用户ID" 访问个人网站,如柳岩: http://weibo.cn/guangxianliuya 因为手机端数据相对精简简单,所以采用输

python爬虫案例-爬取当当网数据

输入关键字,爬取当当网中商品的基本数据,代码如下: 1 # Author:K 2 import requests 3 from lxml import etree 4 from fake_useragent import UserAgent 5 import re 6 import csv 7 8 9 def get_page(key): 10 for page in range(1,50): 11 url = 'http://search.dangdang.com/?key=%s&act=in

Python爬虫项目--爬取链家热门城市新房

本次实战是利用爬虫爬取链家的新房(声明: 内容仅用于学习交流, 请勿用作商业用途) 环境 win8, python 3.7, pycharm 正文 1. 目标网站分析 通过分析, 找出相关url, 确定请求方式, 是否存在js加密等. 2. 新建scrapy项目 1. 在cmd命令行窗口中输入以下命令, 创建lianjia项目 scrapy startproject lianjia 2. 在cmd中进入lianjia文件中, 创建Spider文件 cd lianjia scrapy genspi

[Python爬虫] Selenium爬取新浪微博移动端热点话题及评论 (下)

这篇文章主要讲述了使用python+selenium爬取新浪微博的热点话题和评论信息.其中使用该爬虫的缺点是效率极低,傻瓜式的爬虫,不能并行执行等,但是它的优点是采用分析DOM树结构分析网页源码并进行信息爬取,同时它可以通过浏览器进行爬取中间过程的演示及验证码的输入.这篇文章对爬虫的详细过程就不再论述了,主要是提供可运行的代码和运行截图即可.希望文章对你有所帮助吧~ 参考文章 [python爬虫] Selenium爬取新浪微博内容及用户信息 [Python爬虫] Selenium爬取新浪微博客户

Node.js爬虫-爬取慕课网课程信息

第一次学习Node.js爬虫,所以这时一个简单的爬虫,Node.js的好处就是可以并发的执行 这个爬虫主要就是获取慕课网的课程信息,并把获得的信息存储到一个文件中,其中要用到cheerio库,它可以让我们方便的操作HTML,就像是用jQ一样 开始前,记得 npm install cheerio 为了能够并发的进行爬取,用到了Promise对象 //接受一个url爬取整个网页,返回一个Promise对象 function getPageAsync(url){ return new Promise(

Python爬虫入门 | 爬取豆瓣电影信息

这是一个适用于小白的Python爬虫免费教学课程,只有7节,让零基础的你初步了解爬虫,跟着课程内容能自己爬取资源.看着文章,打开电脑动手实践,平均45分钟就能学完一节,如果你愿意,今天内你就可以迈入爬虫的大门啦~好啦,正式开始我们的第二节课<爬取豆瓣电影信息>吧!啦啦哩啦啦,都看黑板~1. 爬虫原理1.1 爬虫基本原理听了那么多的爬虫,到底什么是爬虫?爬虫又是如何工作的呢?我们先从"爬虫原理"说起.爬虫又称为网页蜘蛛,是一种程序或脚本.但重点在于:它能够按照一定的规则,自动

[python爬虫] Selenium爬取CSDN博客摘要及问题

本文主要是采用Selenium来爬取CSDN的博文摘要,为后面对CSDN的热点技术.近几年专家发表的博客作数据分析.由于采用BeautifulSoup爬取该网站会报错"HTTPError: Forbidden",所以作者采用Selenium爬取.同时,在爬取过程中遇到了局部动态更新的问题,无法定位换页的问题,作者采用Firebug进行分析,也希望读者提出更好的方法.代码下载地址: 一. CSDN博客网站分析及问题 本文主要爬取CSDN专家的博客,因为专家的论文水平相对高点,同时专栏较多

Python爬虫之爬取煎蛋网妹子图

这篇文章通过简单的Python爬虫(未使用框架,仅供娱乐)获取并下载煎蛋网妹子图指定页面或全部图片,并将图片下载到磁盘. 首先导入模块:urllib.request.re.os import urllib.request import re import os urllib.request模块用于获取HTML页面数据 re模块用于通过正则表达式解析并截取HTML页面图片url os模块用于文件夹相关操作 代码不多,直接贴出来,代码解释在注释中: def crawl_jiandan(page, p

python爬虫:爬取易迅网价格信息,并写入Mysql数据库

本程序涉及以下方面知识: 1.python链接mysql数据库:http://www.cnblogs.com/miranda-tang/p/5523431.html   2.爬取中文网站以及各种乱码处理:http://www.cnblogs.com/miranda-tang/p/5566358.html   3.BeautifulSoup使用 4.原网页数据信息不全用字典的方式,把不存在的字段设置为空 详细代码: #!/usr/bin/python # -*- encoding:utf-8 -*