|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
# -*- coding : utf-8 -*-
# -*- author : caoyin -*-
import requests #用来访问网页的库,好比浏览器
from bs4 import BeautifulSoup #爬虫库,用来抓取网页中的信息
import time #时间模块,为了控制爬虫速度,防止由于速度过快,被 ban IP
import csv #用来操作csv的库,这次用来创建表格,存储数据
import urllib.request #用来设置代理Ip
import random #随机选用IP和代码运行时间
import os #创建文件夹,保存信息
def save_to_mysql(post_data):
print("saving......")
db = pymysql.connect("127.0.0.1", "root", "root", "test")
cursor = db.cursor()
effect_row = cursor.executemany("insert into houselist(aeraname , housetype, area, p1, p2, region) values (%s, %s, %s, %s, %s, %s)", post_data)
print(effect_row)
db.commit() # 提交事务
cursor.close()
db.close()
def get_url(pages): #建立获取网址的函数,参数为所需要提取的一级网址起始和终止页码
#设置代理
iplist =['23.244.28.27:3128', '65.49.222.187:8080', '167.99.236.14:80']
proxy_support = urllib.request.ProxyHandler({'http':random.choice(iplist)})
opener = urllib.request.build_opener(proxy_support)
urllib.request.install_opener(opener)
url_list = [] #建立一个空列表,用于存放二级网址
headers = {'UserAgent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'} #http请求头,用于模拟用户访问网页,防止被 ban IP
url_page = ['https://nj.lianjia.com/ershoufang/pg{}/'.format(num) for num in range(pages)] #列表解析式,创建列表,存放一级网址
n = 0 #设定一个计数变量
for page in url_page: #遍历每个一级网址
n+=1 #计数加1
print('正在抓取第{}页链接'.format(n)) #输出正在抓取的是第几个链接
time.sleep(random.randint(2,4)) #代码随机暂停运行2-4秒,控制爬虫速度,防止被 ban IP
page_data = requests.get(page,headers=headers) #用requests库的get方法访问一级网址,参数为链接和请求头
soup = BeautifulSoup(page_data.text,'lxml') #创建一个实例化BeautifulSoup类,类为一级网址的页面,用lxml库解析处理
urls = soup.select('body > div.content > div.leftContent > ul > li > div.info.clear > div.title > a')#用selector选择器根据html标签,在页面中定位二级链接位置,最后返回的是一个列表
for i in urls: #遍历此列表,提取每一个位置
url_list.append(i.get('href')) #提取位置中链接的信息并存入开始创建的空列表中
return url_list #函数返回二级网址列表
def download_inf(folder,url_list): #创建爬虫函数
#这里要先创建一个CSV文件,用于存放爬取的数据
try:
os.mkdir(folder)
except OSError:
pass
os.chdir(folder)
file = open('lianjia.csv','a+',encoding='utf-8-sig') #创建并打开csv文件,参数为文件路径,打开方式ab+: 二进制附加读写方式打开,utf-8-sig编码
writer = csv.writer(file) #对csv进行写入
writer.writerow(['标题','小区名称','总价(万元)','单价(元/平米)','建筑面积(平米)','所在区域','户型','所在楼层','房屋朝向','装修情况']) #写入表头
inf_all = [] #新建一个空列表,存放每一条爬取的数据,用于方便写入文件
headers={'UserAgent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'} #同样先定义一个http请求头
n = 0 #设定一个计数变量
for url in url_list: #遍历每个二级网址emus
n+=1 #计数加1
print('正在抓取第{}个房源'.format(n)) #输出正在抓取的是第几个房源信息
time.sleep(random.randint(2,4)) #代码暂停运行2-4秒,为了控制爬虫速度,防止被 ban IP
web = requests.get(url,headers=headers) #用requests库的get方法访问二级网址,参数为链接和请求头
soup = BeautifulSoup(web.text,'lxml') #创建一个实例化BeautifulSoup类,类为二级网址的页面,用lxml库解析处理
titlel = soup.select('body > div.sellDetailHeader > div > div > div.title > h1')#selector选择器获取房源标题
namel = soup.select('body > div.overview > div.content > div.aroundInfo > div.communityName > a.info') #selector选择器获取小区名称
pricel = soup.select('body > div.overview > div.content > div.price > span.total') #selector选择器获取总价
area_pricel = soup.select('body > div.overview > div.content > div.price > div.text > div.unitPrice > span') #selector选择器获取每平米价格
areal = soup.select('body > div.overview > div.content > div.houseInfo > div.area > div.mainInfo') #获取面积
positionl = soup.select('body > div.overview > div.content > div.aroundInfo > div.areaName > span.info > a:nth-child(1)') #获取位置信息
room_typel = soup.select('body > div.overview > div.content > div.houseInfo > div.room > div.mainInfo') #获取户型信息
floorl = soup.select('#introduction > div > div > div.base > div.content > ul > li:nth-child(2)') #获取楼层信息
house_orientationl = soup.select('#introduction > div > div > div.base > div.content > ul > li:nth-child(7)') #获取房屋朝向信息
renovation_conditionl = soup.select('#introduction > div > div > div.base > div.content > ul > li:nth-child(9)') #获取房屋装修情况信息
for title,name,price,area_price,area,position,room_type,floor,house_orientation,renovation_condition in zip(titlel,namel,pricel,
area_pricel,areal,positionl,room_typel,floorl,house_orientationl,renovation_conditionl): #遍历获取的每一个信息,提取具体的值
data_list = [title.get_text(),name.get_text(),price.get_text(),area_price.get_text(),area.get_text(),position.get_text(),
room_type.get_text(),floor.get_text(),house_orientation.get_text(),renovation_condition.get_text()] #把值以列表形式存入一个变量
inf_all.append(data_list)
file = open('./lianjia.csv','a+',encoding='utf-8-sig',newline='') #打开csv文件
writer = csv.writer(file) #对csv进行写入
for row in inf_all:
writer.writerow(row) #写入爬取的数据
inf_all = [] #清空列表,待存放下一个数据
def main(): #创建一个主函数,汇总以上两个函数
url_list = get_url(pages)
download_inf(folder,url_list)
if __name__ == '__main__': #相当于程序入口,当该文件被直接执行时,该语句后面的代码执行,但该文件作为模块被引用时,后面的代码不被执行
folder = input('请输入保存文件夹:')
pages = int(input('请输入要爬取的页面数量:'))
main() #运行函数 |
|