静态网页爬虫-链家
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(0, 0, '网址')
mysheet.write(0, 1, '小区名称')
mysheet.write(0, 2, '价格')
mysheet.write(0, 3, '户型')
mysheet.write(0, 4, '朝向')
mysheet.write(0, 5, '面积')
mysheet.write(0, 6, '标题')
mysheet.write(0, 7, '发布日期')
mysheet.write(0, 8, 'lat')
mysheet.write(0, 9, '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(1, 101):
# 访问城区的页面, 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 服务。
#对标签属性值的检索字符串,可标注属性检索
以上是关于静态网页爬虫-链家的主要内容,如果未能解决你的问题,请参考以下文章