深圳坪山高铁站,网站制作推广SSL,做网络推广费用,建设银行行号网站查询是什么意思爬取时间#xff1a;2019-10-09爬取难度#xff1a;★★☆☆☆☆请求链接#xff1a;https://wuhan.anjuke.com/sale/爬取目标#xff1a;爬取武汉二手房每一条售房信息#xff0c;包含地理位置、价格、面积等#xff0c;保存为 CSV 文件涉及知识#xff1a;请求库 requ…
爬取时间2019-10-09爬取难度★★☆☆☆☆请求链接https://wuhan.anjuke.com/sale/爬取目标爬取武汉二手房每一条售房信息包含地理位置、价格、面积等保存为 CSV 文件涉及知识请求库 requests、解析库 Beautiful Soup、CSV 文件储存、列表操作、分页判断完整代码https://github.com/TRHX/Python3-Spider-Practice/tree/master/BasicTraining/anjuke其他爬虫实战代码合集持续更新https://github.com/TRHX/Python3-Spider-Practice爬虫实战专栏持续更新https://itrhx.blog.csdn.net/article/category/9351278 文章目录【1x00】页面整体分析【2x00】解析模块【3x00】循环爬取模块【4x00】数据储存模块【5x00】完整代码【6x00】数据截图【7x00】程序不足的地方【1x00】页面整体分析 分析 安居客武汉二手房页面这次爬取实战准备使用 BeautifulSoup 解析库熟练 BeautifulSoup 解析库的用法注意到该页面与其他页面不同的是不能一次性看到到底有多少页以前知道一共有多少页直接一个循环爬取就行了虽然可以通过改变 url 来尝试找到最后一页但是这样就显得不程序员了?因此可以通过 BeautifulSoup 解析 下一页按钮提取到下一页的 url直到没有 下一页按钮 这个元素为止从而实现所有页面的爬取剩下的信息提取和储存就比较简单了 【2x00】解析模块 分析页面可以发现每条二手房信息都是包含在 li 标签内的因此可以使用 BeautifulSoup 解析页面得到所有的 li 标签然后再循环访问每个 li 标签依次解析得到每条二手房的各种信息
def parse_pages(url, num):response requests.get(urlurl, headersheaders)soup BeautifulSoup(response.text, lxml)result_list soup.find_all(li, class_list-item)# print(len(result_list))for result in result_list:# 标题title result.find(a, class_houseListTitle).text.strip()# print(title)# 户型layout result.select(.details-item span)[0].text# print(layout)# 面积cover result.select(.details-item span)[1].text# print(cover)# 楼层floor result.select(.details-item span)[2].text# print(floor)# 建造年份year result.select(.details-item span)[3].text# print(year)# 单价unit_price result.find(span, class_unit-price).text.strip()# print(unit_price)# 总价total_price result.find(span, class_price-det).text.strip()# print(total_price)# 关键字keyword result.find(div, class_tags-bottom).text.strip()# print(keyword)# 地址address result.find(span, class_comm-address).text.replace( , ).replace(\n, )# print(address)# 详情页urldetails_url result.find(a, class_houseListTitle)[href]# print(details_url)if __name__ __main__:start_num 0start_url https://wuhan.anjuke.com/sale/parse_pages(start_url, start_num) 【3x00】循环爬取模块 前面已经分析过该网页是无法一下就能看到一共有多少页的尝试找到最后一页发现一共有50页那么此时就可以搞个循环一直到第50页就行了但是如果有一天页面数增加了呢那么代码的可维护性就不好了我们可以观察 下一页按钮 当存在下一页的时候是 a 标签并且带有下一页的 URL不存在下一页的时候是 i 标签因此可以写个 if 语句判断是否存在此 a 标签若存在表示有下一页然后提取其 href 属性并传给解析模块实现后面所有页面的信息提取此外由于安居客有反爬系统我们还可以利用 Python中的 random.randint() 方法在两个数值之间随机取一个数传入 time.sleep() 方法实现随机暂停爬取
# 判断是否还有下一页
next_url soup.find_all(a, class_aNxt)
if len(next_url) ! 0:num 1print(第 str(num) 页数据爬取完毕)# 3-60秒之间随机暂停time.sleep(random.randint(3, 60))parse_pages(next_url[0].attrs[href], num)
else:print(所有数据爬取完毕) 【4x00】数据储存模块 数据储存比较简单将每个二手房信息组成一个列表依次写入到 anjuke.csv 文件中即可
results [title, layout, cover, floor, year, unit_price, total_price, keyword, address, details_url]
with open(anjuke.csv, a, newline, encodingutf-8-sig) as f:w csv.writer(f)w.writerow(results) 【5x00】完整代码 #
# --*-- coding: utf-8 --*--
# Time : 2019-10-09
# Author : TRHX
# Blog : www.itrhx.com
# CSDN : https://blog.csdn.net/qq_36759224
# FileName: anjuke.py
# Software: PyCharm
# import requests
import time
import csv
import random
from bs4 import BeautifulSoupheaders {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
}def parse_pages(url, num):response requests.get(urlurl, headersheaders)soup BeautifulSoup(response.text, lxml)result_list soup.find_all(li, class_list-item)# print(len(result_list))for result in result_list:# 标题title result.find(a, class_houseListTitle).text.strip()# print(title)# 户型layout result.select(.details-item span)[0].text# print(layout)# 面积cover result.select(.details-item span)[1].text# print(cover)# 楼层floor result.select(.details-item span)[2].text# print(floor)# 建造年份year result.select(.details-item span)[3].text# print(year)# 单价unit_price result.find(span, class_unit-price).text.strip()# print(unit_price)# 总价total_price result.find(span, class_price-det).text.strip()# print(total_price)# 关键字keyword result.find(div, class_tags-bottom).text.strip()# print(keyword)# 地址address result.find(span, class_comm-address).text.replace( , ).replace(\n, )# print(address)# 详情页urldetails_url result.find(a, class_houseListTitle)[href]# print(details_url)results [title, layout, cover, floor, year, unit_price, total_price, keyword, address, details_url]with open(anjuke.csv, a, newline, encodingutf-8-sig) as f:w csv.writer(f)w.writerow(results)# 判断是否还有下一页next_url soup.find_all(a, class_aNxt)if len(next_url) ! 0:num 1print(第 str(num) 页数据爬取完毕)# 3-60秒之间随机暂停time.sleep(random.randint(3, 60))parse_pages(next_url[0].attrs[href], num)else:print(所有数据爬取完毕)if __name__ __main__:with open(anjuke.csv, a, newline, encodingutf-8-sig) as fp:writer csv.writer(fp)writer.writerow([标题, 户型, 面积, 楼层, 建造年份, 单价, 总价, 关键字, 地址, 详情页地址])start_num 0start_url https://wuhan.anjuke.com/sale/parse_pages(start_url, start_num) 【6x00】数据截图 【7x00】程序不足的地方 虽然使用了随机暂停爬取的方法但是在爬取了大约 20 页的数据后依然会出现验证页面导致程序终止 原来设想的是可以由用户手动输入城市的拼音来查询不同城市的信息方法是把用户输入的城市拼音和其他参数一起构造成一个 URL然后对该 URL 发送请求判断请求返回的代码如果是 200 就代表可以访问也就是用户输入的城市是正确的然而发现即便是输入错误该 URL 依然可以访问只不过会跳转到一个正确的页面没有搞清楚是什么原理也就无法实现由用户输入城市来查询这个功能