8小時Python零基礎輕鬆入門
實習期間老闆需要整合土地資源數據。之前由於都是在中國土地網上對每個城市的數據進行爬取,但是出於精益求精的精神,決定再對每個城市的自然資源和規劃局再次進行爬取,這樣可以對數據進行比對。或者添加新數據或者去重。
其實每個城市的自然資源和規劃局網站結構基本類似,本次我們就拿徐州市來做一個案例分析。
爬取目標
如圖所示。
我們爬取字段如下:
- 行政區
- 項目名稱
- 項目位置
- 合同編號
- 電子監管
- 面積_公頃
- 土地來源
- 供地方式
- 土地使用年限
- 行業分類
- 土地用途
- 土地級別
- 成交價格_萬元
- 土地使用權人
- 約定容積率_下限
- 約定容積率_上限
- 約定交地時間
- 約定開工時間
- 約定竣工時間
- 批准單位
- 簽訂日期
網頁分析
首先我們打開官網
接着向下滑動網頁,找到土地市場,然後點擊進去。
接着跳轉到新的鏈接,我們依次點擊土地市場,供地結果,下面出來的招拍、協議出讓、劃撥用地就是我們此次需要爬取的三個內容。
我們先點擊招拍掛出結果公告,右邊就顯示出項目名稱。
我們點擊進去項目名稱,然後就是各個土地的拍賣和公司信息。
看起來邏輯很簡單,我們只需要先對項目名稱的鏈接進行爬取,然後根據爬取到的鏈接再進去爬取具體的內容。
但是我們在對一個具體的鏈接使用requests庫進行測試的時候,發現返回的只是基礎的網頁內容,不涉及到具體的數據。這時候就知道,前後端是分離的,我們需要找到真正的鏈接。
通過不斷查找,我們發現真正的項目鏈接竟然隱藏在表格的iframe的鏈接中。這樣這樣就找到了真正的鏈接,依次進行爬取。
爬取內容
首先我們先爬取項目名稱的鏈接。我們將獲取到的鏈接保存到txt文件中,方面後面調用。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
import time
browser=webdriver.Chrome()
wait=WebDriverWait(browser,10)
def search():
browser.get('http://zrzy.jiangsu.gov.cn//gtapp/xxgk/tdsc_getGdxminfo.action?xzqhdm=320300&xsys=1&lx=1')
get_products()
def next_page():
submit = wait.until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="gdxmPagingHtml"]/a[3]')))
submit.click()
get_products()
ss=[]
def get_products():
html=browser.page_source
doc=pq(html)
#print(doc)
comments = []
items=doc('.xxgk-listz #gdxmTableHtml .taleft1').items()
for item in items:
lis = {}
lis['link']='http://zrzy.jiangsu.gov.cn/gtapp/xxgk/'+item.find('a').attr('href')
comments.append(lis)
with open('劃撥用地.txt', 'a+') as f:
for comment in comments:
f.write('{} \n'.format(
comment['link']))
print('當前頁面爬取完成')
def main():
print("正在輸出第1頁")
search()
for i in range(2,43):
time.sleep(1)
print("正在輸出第{}頁".format(i))
next_page()
browser.close()
if __name__ == '__main__':
main()
接着我們讀取txt中的鏈接,分別進入到每個網頁對具體內容進行爬取,並保存到CSV文件中。
# coding='utf-8'
import requests
from bs4 import BeautifulSoup
import time
import csv
# 首先我們寫好抓取網頁的函數
def get_html(url):
try:
r = requests.get(url,timeout=30)
r.raise_for_status()
r.encoding='utf-8'
return r.text
except:
return " ERROR "
def get_content(url):
#global values
values = []
html=get_html(url)
soup=BeautifulSoup(html,'lxml')
行政區=soup.find('span',attrs={'id':'XZQ_DM'}).text.strip()
項目名稱=soup.find('span', attrs={'id': 'XM_MC'}).text.strip()
項目位置 = soup.find('span', attrs={'id': 'TD_ZL'}).text.strip()
合同編號 = soup.find('span', attrs={'id': 'BH'}).text.strip()
電子監管 = soup.find('span', attrs={'id': 'DZ_BA_BH'}).text.strip()
面積_公頃= soup.find('span', attrs={'id': 'GY_MJ'}).text.strip()
土地來源 = soup.find('span', attrs={'id': 'TD_LY'}).text.strip()
供地方式=soup.find('span', attrs={'id': 'GY_FS'}).text.strip()
土地使用年限 = soup.find('span', attrs={'id': 'CR_NX'}).text.strip()
行業分類 = soup.find('span', attrs={'id': 'HY_FL'}).text.strip()
土地用途= soup.find('span', attrs={'id': 'TD_YT'}).text.strip()
土地級別= soup.find('span', attrs={'id': 'TD_JB'}).text.strip()
成交價格_萬元= soup.find('span', attrs={'id': 'JE'}).text.strip()
土地使用權人= soup.find('span', attrs={'id': 'SRR'}).text.strip()
約定容積率_下限= soup.find('span', attrs={'id': 'MIN_RJL'}).text.strip()
約定容積率_上限= soup.find('span', attrs={'id': 'MAX_RJL'}).text.strip()
約定交地時間= soup.find('span', attrs={'id': 'JD_SJ'}).text.strip()
約定開工時間= soup.find('span', attrs={'id': 'DG_SJ'}).text.strip()
約定竣工時間 = soup.find('span', attrs={'id': 'JG_SJ'}).text.strip()
批准單位= soup.find('span', attrs={'id': 'PZ_JG'}).text.strip()
簽訂日期= soup.find('span', attrs={'id': 'QD_RQ'}).text.strip()
lis=[行政區,項目名稱,項目位置,合同編號 ,電子監管 ,面積_公頃,土地來源,供地方式,土地使用年限 ,行業分類 ,土地用途,土地級別,成交價格_萬元,土地使用權人,約定容積率_下限,約定容積率_上限,約定交地時間,約定開工時間,約定竣工時間,批准單位,簽訂日期]
values.append(lis)
return values
def outfile(values):
with open("xuzhou_huabo.csv","a+",newline='',encoding='utf8')as csvfile:
writer = csv.writer(csvfile)
#writer.writerow(['行政區','項目名稱','項目位置','合同編號' ,'電子監管' ,'面積_公頃','土地來源','供地方式','土地使用年限' ,'行業分類' ,'土地用途','土地級別','成交價格_萬元','土地使用權人','約定容積率_下限','約定容積率_上限','約定交地時間','約定開工時間','約定竣工時間','批准單位','簽訂日期'])
#for row in values:
#writer.writerow(row)
writer.writerows(values)
def main():
with open('劃撥用地.txt', 'r') as f:
count=0
for line in f:
count+=1
print("正在解析第{}個頁面,一共有756個頁面".format(count))
time.sleep(1)
values=get_content(line)
outfile(values)
print("所有信息都已經爬取完成")
if __name__ == '__main__':
main()
也可以將抓取到的數據保存到txt文件中。
# coding='utf-8'
import requests
from bs4 import BeautifulSoup
import time
def get_html(url):
try:
r = requests.get(url,timeout=30)
r.raise_for_status()
r.encoding='utf-8'
return r.text
except:
return " ERROR "
def get_content(url):
comments=[]
html=get_html(url)
soup=BeautifulSoup(html,'lxml')
comment={}
comment['行政區']=soup.find('span',attrs={'id':'XZQ_DM'}).text.strip()
comment['項目名稱'] =soup.find('span', attrs={'id': 'XM_MC'}).text.strip()
comment['項目位置'] = soup.find('span', attrs={'id': 'TD_ZL'}).text.strip()
comment['合同編號'] = soup.find('span', attrs={'id': 'BH'}).text.strip()
comment['電子監管號'] = soup.find('span', attrs={'id': 'DZ_BA_BH'}).text.strip()
comment['面積(公頃)'] = soup.find('span', attrs={'id': 'GY_MJ'}).text.strip()
comment['土地來源'] = soup.find('span', attrs={'id': 'TD_LY'}).text.strip()
comment['供地方式']=soup.find('span', attrs={'id': 'GY_FS'}).text.strip()
comment['土地使用年限'] = soup.find('span', attrs={'id': 'CR_NX'}).text.strip()
comment['行業分類'] = soup.find('span', attrs={'id': 'HY_FL'}).text.strip()
comment['土地用途'] = soup.find('span', attrs={'id': 'TD_YT'}).text.strip()
comment['土地級別'] = soup.find('span', attrs={'id': 'TD_JB'}).text.strip()
comment['成交價格(萬元)'] = soup.find('span', attrs={'id': 'JE'}).text.strip()
comment['土地使用權人'] = soup.find('span', attrs={'id': 'SRR'}).text.strip()
comment['約定容積率(下限)'] = soup.find('span', attrs={'id': 'MIN_RJL'}).text.strip()
comment['約定容積率(上限)'] = soup.find('span', attrs={'id': 'MAX_RJL'}).text.strip()
comment['約定交地時間'] = soup.find('span', attrs={'id': 'JD_SJ'}).text.strip()
comment['約定開工時間'] = soup.find('span', attrs={'id': 'DG_SJ'}).text.strip()
comment['約定竣工時間'] = soup.find('span', attrs={'id': 'JG_SJ'}).text.strip()
comment['批准單位'] = soup.find('span', attrs={'id': 'PZ_JG'}).text.strip()
comment['簽訂日期'] = soup.find('span', attrs={'id': 'QD_RQ'}).text.strip()
comments.append(comment)
return comments
def outfile(dict):
with open('xuzhou.txt','a+',encoding='utf-8')as f:
for comment in dict:
f.write('行政區:{} \t 項目名稱:{} \t 項目位置:{} \t 合同編號:{} \t 電子監管號:{} \t 面積(公頃):{} \t 土地來源:{} \t 供地方式:{} \t 土地使用年限:{} \t 行業分類:{} \t 土地用途:{} \t 土地級別:{} \t 成交價格(萬元):{} \t 土地使用權人:{} \t 約定容積率(下限):{} \t 約定容積率(上限):{} \t 約定交地時間:{} \t 約定開工時間:{} \t 約定竣工時間:{} \t 批准單位:{} \t 簽訂日期:{} \n'.format(
comment['行政區'], comment['項目名稱'], comment['項目位置'], comment['合同編號'], comment['電子監管號'],comment['面積(公頃)'],comment['土地來源'],comment['供地方式'],comment['土地使用年限'] ,comment['行業分類'],comment['土地用途'],comment['土地級別'],comment['成交價格(萬元)'] ,comment['土地使用權人'] ,comment['約定容積率(下限)'],comment['約定容積率(上限)'] ,comment['約定交地時間'] ,comment['約定開工時間'] ,comment['約定竣工時間'] ,comment['批准單位'],comment['簽訂日期'] ))
print('當前頁面爬取完成')
def main():
with open('TTBT.txt', 'r') as f:
count=0
for line in f:
count+=1
print("正在解析第{}個頁面,一共有4122個頁面".format(count))
time.sleep(1)
values=get_content(line)
outfile(values)
print("所有信息都已經爬取完成")
if __name__ == '__main__':
main()
最終就獲取到了所有的數據。
總結
這個網站比較簡單,在爬取的過程中沒有遇到什麼大的困難。也就是兩個點。第一點就是真實鏈接的尋找,第二點就是設置一個睡眠時間,防止爬取速度過快,網頁沒有加載出來。
下一篇會寫爬取中國土地網的數據,這裏面涉及到的難點就比較多了。