利用Beautifulsoup+Xpath爬取安居客官网全国600多城市二手房信息并存储mongodb

首先给我们爬虫做个知识点的简介:
网页解析库:Beautifulsoup、xpath
请求库:requests
数据存储:pymongo

分析目标网站:安居客官网
安居客官网

我们从以这些城市作为起始站点,获取每一个城市二手房的链接,从Chrome审查看一下:
这里写图片描述
我们可以看到这些城市的‘href’元素是他们的下一级页面的url,总共有600多个城市,也就是我们可以找到600多个url。
但都是:https://anshan.anjuke.com这种形式,这样点进去并不是我们需要的相应城市的二手房界面的url。对比一下:
这里写图片描述
可以发现在原有的url后面多个‘/sale’,然后我们想要获得下一页,可以直接改变url后面的数值就行。

数据解析部分:
初始页面的城市的url我们用xpath,直接chrome审查copy xpath:

def first_url():#定义解析一百个城市的函数
    link = 'https://www.anjuke.com/sy-city.html'
    r = requests.get(link, headers=headers)
    html = etree.HTML(r.text)
    #解析一百个城市的链接地址
    Urls = html.xpath('//*[@class="city-itm"]/div[2]/ul/li/div/a/@href')
    #返回地址以供主函数调用
    return Urls
    #print(titles)

可以看到打印出的是所有城市的url地址。
接下来我们写爬取这些城市二手房信息的主函数:
这里主要用的bs解析,因为xpath在这里解析比较麻烦,且xpath都比较长
例如这是第一个//*[@id=”houselist-mod-new”]/li[1]/div[2]/div[1]/a/text(),xpath提取出来会比较麻烦。
构建一个information字典,我们一共提取了10个字段。

def main():
    #调用一百个城市函数地址的值
    ism = first_url()
    for Url in ism:
        #print(title)
        #以列表形式传入titl
        for num in range(1, 50):#将titl进行翻页的操作,并补全url
            i = num
            url = Url + '/sale/p{}'.format(i)
            #print(titl)
            r = requests.get(url, headers=headers)
            #time.sleep(5)
            print('现在爬取的是第', i, '页')
            soup = BeautifulSoup(r.text, 'lxml')
            house_list = soup.find_all('li', class_="list-item")
            if len(house_list) < 10:
                continue
            #return house_list
            for house in house_list:
                try:
                    information = {
                        "name": house.find('div', class_='house-title').a.text.strip(),
                        "price": house.find('span', class_='price-det').text.strip(),
                        "price_area": house.find('span', class_='unit-price').text.strip(),
                        "no_room": house.find('div', class_='details-item').span.text,
                        "area": house.find('div', class_='details-item').contents[3].text,
                        "floor": house.find('div', class_='details-item').contents[5].text,
                        "year": house.find('div', class_='details-item').contents[7].text,
                        "broker": house.find('span', class_='brokername').text[1:],
                        "address": house.find('span', class_='comm-address').text.strip(),
                        "tags": [i.text for i in house.find_all('span', class_='item-tags')]
                    }
                    print(information)
                except:
                    continue
                save_to_mongo(information)

接下类似是关于数据的存储问题,这部分主要参考@崔大的视频教程,存储到mongodb。

MONGO_URL = 'localhost'
MONGO_DB = '安居客'
MONGO_TABLE = 'city1'
client = pymongo.MongoClient(MONGO_URL,connect=False)
db=client[MONGO_DB]

这部分可以直接写在一个文件里,也可以放在另一个.py里,用from xx(另一个.py) inport *的方式导入。
相应的存储函数:

def save_to_mongo(result):

    try:
        if db[MONGO_TABLE].insert(result):
            print('存储到MONGODB成功', result)
        else:print('插入失败')
    except Exception:
        print('存储到MONGODB失败', result)

这里会在控制台打印出我们的存储内容。

最后补充一点:这里跟着崔大学习的主要是try: except这个抛出异常的方法。但是在数据存储的部分有一个问题,就是

                    print(information)
                except:
                    continue
                save_to_mongo(information)

这里有的时候会因为页面没有字典里的某个键值,导致无法存储进去,因此整个程序也没有颁发运行,希望有大神知道哪里的原因可以指导下。

总的代码如下:

import time
from bs4 import BeautifulSoup
import requests
from lxml import etree
import pymongo
#from multiprocessing import Pool

headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'}

MONGO_URL = 'localhost'
MONGO_DB = '安居客'
MONGO_TABLE = 'city1'

client = pymongo.MongoClient(MONGO_URL,connect=False)
db=client[MONGO_DB]


def first_url():#定义解析一百个城市的函数
    link = 'https://www.anjuke.com/sy-city.html'
    r = requests.get(link, headers=headers)
    html = etree.HTML(r.text)
    #解析一百个城市的链接地址
    Urls = html.xpath('//*[@class="city-itm"]/div[2]/ul/li/div/a/@href')
    #返回地址以供主函数调用
    return Urls
    #print(titles)
def save_to_mongo(result):

    try:
        if db[MONGO_TABLE].insert(result):
            print('存储到MONGODB成功', result)
        else:print('插入失败')
    except Exception:
        print('存储到MONGODB失败', result)

def main():
    #调用一百个城市函数地址的值
    ism = first_url()
    for Url in ism:
        #print(title)
        #以列表形式传入titl
        for num in range(1, 50):#将titl进行翻页的操作,并补全url
            i = num
            url = Url + '/sale/p{}'.format(i)
            #print(titl)
            r = requests.get(url, headers=headers)
            #time.sleep(5)
            print('现在爬取的是第', i, '页')
            soup = BeautifulSoup(r.text, 'lxml')
            house_list = soup.find_all('li', class_="list-item")
            if len(house_list) < 10:
                continue
            #return house_list
            for house in house_list:
                try:
                    information = {
                        "name": house.find('div', class_='house-title').a.text.strip(),
                        "price": house.find('span', class_='price-det').text.strip(),
                        "price_area": house.find('span', class_='unit-price').text.strip(),
                        "no_room": house.find('div', class_='details-item').span.text,
                        "area": house.find('div', class_='details-item').contents[3].text,
                        "floor": house.find('div', class_='details-item').contents[5].text,
                        "year": house.find('div', class_='details-item').contents[7].text,
                        "broker": house.find('span', class_='brokername').text[1:],
                        "address": house.find('span', class_='comm-address').text.strip(),
                        "tags": [i.text for i in house.find_all('span', class_='item-tags')]
                    }
                    print(information)
                except:
                    continue
                save_to_mongo(information)
            #   time.sleep(30)
            # print(house_list)

if __name__ == '__main__':
    main()
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以给你提供一个大致的思路: 1. 安装selenium和pymongo库 ``` pip install selenium pymongo ``` 2. 下载Chrome浏览器和相应版本的chromedriver,并配置环境变量 3. 使用selenium模拟浏览器打开豆瓣读书网站,并搜索需要的书籍,获取搜索结果页面的源代码 ```python from selenium import webdriver # 打开浏览器 driver = webdriver.Chrome() # 打开网页 url = "https://book.douban.com/" driver.get(url) # 搜索书籍 keyword = "Python" search_box = driver.find_element_by_xpath("//input[@name='search_text']") search_box.send_keys(keyword) search_box.submit() # 获取搜索结果页面的源代码 page_source = driver.page_source # 关闭浏览器 driver.quit() ``` 4. 使用BeautifulSoup解析页面源代码,获取需要的数据 ```python from bs4 import BeautifulSoup # 解析页面源代码 soup = BeautifulSoup(page_source, "html.parser") # 获取书籍列表 book_list = soup.find_all("li", class_="subject-item") # 遍历书籍列表,获取书籍信息 for book in book_list: # 获取书名 title = book.find("h2").a["title"] # 获取评分 rating = book.find("span", class_="rating_nums").get_text() # 获取出版信息 pub_info = book.find("div", class_="pub").get_text().strip() # 存储数据到数据库 db.books.insert_one({"title": title, "rating": rating, "pub_info": pub_info}) ``` 5. 将数据存储MongoDB中 ```python from pymongo import MongoClient # 连接MongoDB数据库 client = MongoClient("mongodb://localhost:27017/") db = client["douban"] # 存储数据到数据库 for book in book_list: # 获取书籍信息 ... # 存储数据到数据库 db.books.insert_one({"title": title, "rating": rating, "pub_info": pub_info}) ``` 以上是一个简单的爬虫程序,可以根据自己的需求进行修改和优化。另外需要注意的是,爬取网站数据需要遵守网站的相关规定和法律法规,不得进行恶意爬取和商业利用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值