静态网页爬虫-链家

Posted 柴立不阿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了静态网页爬虫-链家相关的知识,希望对你有一定的参考价值。

python+selenium 3个线程 12小时2w5s条数据 无验证码 

难度:




'''python

from concurrent.futures import ThreadPoolExecutor
from selenium import webdriver
import xlwt
from bs4 import BeautifulSoup 
import re

class LianJia:

workbook = xlwt.Workbook(encoding='utf-8')
mysheet = workbook.add_sheet('housePrice')
mysheet.write(00'网址')
mysheet.write(01'小区名称')
mysheet.write(02'价格')
mysheet.write(03'户型')
mysheet.write(04'朝向')
mysheet.write(05'面积')
mysheet.write(06'标题')
mysheet.write(07'发布日期')
mysheet.write(08'lat')
mysheet.write(09'lon')
i = 1

def __init__(self):

    # 使用内置线程池, 设置最大线程数
    self.executor = ThreadPoolExecutor(max_workers=2)
    # 声明Chrome浏览器对象
    self.driver = webdriver.Chrome(r'D:\Python\CGTWR\lianjia\chromedriver.exe')
    # 声明更多的Chrome浏览器对象
    self.driver2 = webdriver.Chrome(r'D:\Python\CGTWR\lianjia\chromedriver.exe')
    self.driver3 = webdriver.Chrome(r'D:\Python\CGTWR\lianjia\chromedriver.exe')

def house_detail(self, item, url, driver):
    """获取一间房子的详情信息"""
    driver.get(url)  # 访问一间房子的详情页
    item['houseURL'] = url
    # 标题
    item['title'] = driver.find_element_by_tag_name('h1').text
    # 价格
    item['price'] = driver.find_element_by_css_selector('span.total').text
    house_info = driver.find_elements_by_css_selector('div.mainInfo')
    item['room'] = house_info[0].text  # 户型
    item['faceTo'] = house_info[1].text  # 朝向
    item['area'] = house_info[2].text  # 面积
    # 小区名 find_element_by_xpath("//标签名[@属性=‘属性值’]")
    item['communityName'] = driver.find_element_by_css_selector('div.communityName a.info').text
    # 发布日期  先在整个文档里查找div,再在div里查找p节点
    assert isinstance(driver.find_element_by_xpath('//div[@class="transaction"]/div[2]/ul/li/span[2]').text, object)
    item['releaseDate'] = driver.find_element_by_xpath('//div[@class="transaction"]/div[2]/ul/li/span[2]').text
    html = driver.page_source
    soup = BeautifulSoup(html, "html.parser")
    titles = soup.select("body script")[30]
    pattern = "resblockPosition:'.*?'"
    string = str(titles)
    target_content = re.findall(pattern, string)
    target_content = target_content[0]
    target_content = target_content.replace('resblockPosition:''')
    target_content = target_content.replace('\'''')
    target_content = target_content.replace('\"''')
    item['lat'] = target_content.split(',')[0]
    item['lon'] = target_content.split(',')[1]
    print(item)
    self.mysheet.write(self.i, 0, item['houseURL'])
    self.mysheet.write(self.i, 1, item['communityName'])
    self.mysheet.write(self.i, 2, item['price'])
    self.mysheet.write(self.i, 3, item['room'])
    self.mysheet.write(self.i, 4, item['faceTo'])
    self.mysheet.write(self.i, 5, item['area'])
    self.mysheet.write(self.i, 6, item['title'])
    self.mysheet.write(self.i, 7, item['releaseDate'])
    self.mysheet.write(self.i, 8, item['lat'])
    self.mysheet.write(self.i, 9, item['lon'])
    self.i += 1
    self.workbook.save('ceshi.xls')

def asyn_page(self, item, url_list):
    """异步处理线程, 让两个driver同时访问不同的页面"""
    self.executor.submit(self.house_detail, item=dict(item), url=url_list[0], driver=self.driver2)
    self.executor.submit(self.house_detail, item=dict(item), url=url_list[1], driver=self.driver3)

def house_list(self, item):
    """获取一个城区中所有房子的详情页链接"""
    for page in range(1101):
        # 访问城区的页面, co32表示最新发布
        self.driver.get(item['partURL'] + f'pg{page}co32/')
        # 获取到所有的房子链接
        house_ls = self.driver.find_elements_by_xpath('//ul[@class="sellListContent"]//div[@class="title"]/a')
        # 生成url列表
        house_url_ls = [house.get_attribute("href"for house in house_ls]
        # 循环内的作用, 同时给url_list参数提供两个不同的值
        for i in range(0, len(house_url_ls), 2):
            if i < len(house_url_ls) - 1:
                self.asyn_page(item=dict(item), url_list=[house_url_ls[i], house_url_ls[i + 1]])
        else:
            print(f'>>[{item["partName"]}]区,第[{page}]页, 处理完成')
    else:
        print(f'>[{item["partName"]}]处理完成')

def run(self):
    """获取所有城区的页面链接"""
    # 访问二手房网址
    self.driver.get('https://bj.lianjia.com/ershoufang/')
    # 获取所有城区的元素对象
    temp_ls = self.driver.find_elements_by_xpath('//div[@class="position"]/dl[2]/dd/div[1]/div/a')
       # 城区名
    part_name_ls = [ele.text for ele in temp_ls]
    # 城区链接
    part_url_ls = [ele.get_attribute("href"for ele in temp_ls]
    item = {}  # 初始化一个容器, 用来存放房子的信息
    for i in range(len(temp_ls)):
        item['partName'] = part_name_ls[i]  # 城区名
        item['partURL'] = part_url_ls[i]  # 城区页面链接
        self.house_list(dict(item))  # 传递深拷贝的item对象

def __del__(self):
    self.driver.close()  # 关闭浏览器1
    self.driver2.close()  # 关闭浏览器2
    self.driver3.close()  # 关闭浏览器3
    print('>>>>[Well Done]')

if name__ == '__main':
   lj = LianJia()
   lj.run()
'''

注:#<meta name="location" content="province=河北;city=石家庄;coord=38.048731,114.518633">
#<meta> 标签提供关于 HTML 文档的元数据。它不会显示在页面上,但是对于机器是可读的。可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务。
#对标签属性值的检索字符串,可标注属性检索


以上是关于静态网页爬虫-链家的主要内容,如果未能解决你的问题,请参考以下文章

爬虫练习三:爬取链家二手房信息

python爬虫:爬取链家深圳全部二手房的详细信息

链家新房爬虫

爬虫之链家网

通过爬虫抓取链家二手房数据

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