landchina数据爬取(2020.1.6)

landchina数据爬取

从简书里(https://www.jianshu.com/p/97c7e903acad)学习,爬取本地市19年度的土地出让记录。
python 本来也没太多接触,里面涉及几个方面的内容:

proxy:

这是为了规避大量爬取landchina数据导致被封IP而提及的代理,我这边只是爬取少量,不需要用到。

redis

远程字典服务,之前没有接触,作者用这个应该是为了分布式的爬取,实际上我是不需要的,不过为了了解该知识,也蛮用了一下。

r = redis.Redis(host='127.0.0.1', port=6379, db=0)  # host自己的ip地址

注意要下载Redis-server,并运行,redis官网上没有win版本,需要去github上下载。

chrome driver

这边调用的是chrome 的无界面浏览,下载跟机子上安装的chrome一致的chromedriver,国内淘宝有镜像(http://npm.taobao.org/mirrors/chromedriver/)
下载后设置path就好。至于里面的chrome options,headless等方法的变化,按提示改下就好。

chrome_options.add_argument("--headless")
driver = webdriver.Chrome(options=chrome_options)  # 打开chrome_headless浏览器

pymongo

这个也是一个nosql,这边没用到,有空再去了解一下mongo。

Beautiful Soup

Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下:

Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。
Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。

xlwt

这个是python里的一个excel库,查下资料可以现学现用。

get cookie & createHeaders

打开一个网页获得一个cookie,并构造出一个header,用于发送get请求,获取详细的土地供应信息页面。

retry

@retry(tries=5, delay=2) #出错重试5次,延迟2秒

倒不一定用到,后面我把他注释掉,不然一开始再调试的时候,因为有错误,一直跳出新的chromedriver,我还以为是分布式多线程的因素。。。

详细的代码如下:

main1.py

#coding=utf-8
import time
import re
import redis
from bs4 import BeautifulSoup
from selenium import webdriver
import random
import sys
import requests
r = redis.Redis(host='127.0.0.1', port=6379, db=0)  # host自己的ip地址
chrome_options = webdriver.ChromeOptions()
#chrome_options.add_argument('--proxy-server=http://' + proxy)
chrome_options.add_argument("--headless")
driver = webdriver.Chrome(options=chrome_options)  # 打开chrome_headless浏览器
driver.get('http://www.landchina.com/default.aspx?tabid=263&ComName=default')  # 打开界面
i = 1
l = 0
date_list = []
time.sleep(8)
driver.find_element_by_id('TAB_QueryConditionItem270').click()
def page_zh(i, l):
    # 获取本时间段内的总页数(方法)int(reg[0])
    zys = driver.find_elements_by_css_selector(".pager")
    if (zys != []):
        str = zys[1].text;
        reg = re.findall(r'\d+', str)
        pages = int(reg[0])
        print("总页数为:" + reg[0])
        tds = driver.find_elements_by_css_selector(".pager>input")
        # 清空文本方法
        tds[0].clear()
        tds[0].send_keys(i)
        print("第" + tds[0].get_attribute("value") + "页")
        tds[1].click()
    elif (zys == []):
        pages = 1
    time.sleep(4)
    # 获取页面html
    html = driver.find_element_by_id('TAB_contentTable').get_attribute('innerHTML')
    soup = BeautifulSoup(html, 'html.parser')  # 对html进行解析
    href_ = soup.select('.queryCellBordy a')
    for line in href_:
        print("http://www.landchina.com/" + line['href'])
        link = "http://www.landchina.com/" + line['href']
        # 链接redis
        r.sadd('mylist2', "http://www.landchina.com/" + line['href'])
        url = "http://www.landchina.com/" + line['href']
    if (i < pages):
        i = i + 1
        page_zh(i, l)
    else:
        print("本次采集结束!!!")
    # 关闭浏览器(selenium)
    driver.quit()
def llq_main(start, end):
    print(start, end)
    time.sleep(2)
    # 对时间条件进行赋值
    driver.find_element_by_id('TAB_queryDateItem_270_1').clear()
    driver.find_element_by_id('TAB_queryDateItem_270_1').send_keys(start)
    driver.find_element_by_id('TAB_queryDateItem_270_2').clear()
    driver.find_element_by_id('TAB_queryDateItem_270_2').send_keys(end)
    # 进行行政区的选择
    driver.find_element_by_id('TAB_QueryConditionItem256').click()
    driver.execute_script("document.getElementById('TAB_queryTblEnumItem_256_v').setAttribute('type', 'text');")
    driver.find_element_by_id('TAB_queryTblEnumItem_256_v').clear()
    driver.find_element_by_id('TAB_queryTblEnumItem_256_v').send_keys('3503')  # 3701是济南; 37是山东
    driver.find_element_by_id('TAB_QueryButtonControl').click()  # 查询操作
    page_zh(i, l)
if __name__ == '__main__':
    llq_main('2019-10-01', '2019-12-31')
       

main2.py

#coding=utf-8
import requests
from pyquery import PyQuery as pq
from redis import StrictRedis
from selenium import webdriver
import time
from pymongo import MongoClient
from bs4 import BeautifulSoup
from retry import retry
import random
import xlwt
r = StrictRedis(host='127.0.0.1', port=6379, db=0)
client = MongoClient()
db = client['landchina_qd']
collection = db['landchina_qd']
proxy = '127.0.0.1:1080'
proxies = {
    'http': 'socks5://' + proxy,
    'https': 'socks5://' + proxy
}
def get_info(url, headers):
    req = requests.get(url, headers=headers)
    soup = BeautifulSoup(req.text, "html.parser")
    items = soup.find(
        'table', id="mainModuleContainer_1855_1856_ctl00_ctl00_p1_f1")
    # 所需信息组成字典
    info = {}
    # 行政区
    division = items.find(
        'span', id="mainModuleContainer_1855_1856_ctl00_ctl00_p1_f1_r1_c2_ctrl").get_text()
    info['行政区'] = division
    # 项目名称
    prjname = items.find(
        'span', id="mainModuleContainer_1855_1856_ctl00_ctl00_p1_f1_r17_c2_ctrl").get_text()
    info['项目名称'] = prjname
    # 项目位置
    location = items.find(
        'span', id="mainModuleContainer_1855_1856_ctl00_ctl00_p1_f1_r16_c2_ctrl").get_text()
    info['项目位置'] = location
    # 面积(公顷)
    square = items.find(
        'span', id="mainModuleContainer_1855_1856_ctl00_ctl00_p1_f1_r2_c2_ctrl").get_text()
    info['面积'] = square
    # 土地用途
    purpose = items.find(
        'span', id="mainModuleContainer_1855_1856_ctl00_ctl00_p1_f1_r3_c2_ctrl").get_text()
    info['土地用途'] = purpose
    # 约定开工时间
    kgtime = items.find(
        'span', id="mainModuleContainer_1855_1856_ctl00_ctl00_p1_f1_r22_c2_ctrl").get_text()
    info['约定开工时间'] = kgtime
    # 约定竣工时间
    jgtime = items.find(
        'span', id="mainModuleContainer_1855_1856_ctl00_ctl00_p1_f1_r22_c4_ctrl").get_text()
    info['约定竣工时间'] = jgtime
    # 合同签订日期
    qdtime = items.find(
        'span', id="mainModuleContainer_1855_1856_ctl00_ctl00_p1_f1_r14_c4_ctrl").get_text()
    info['合同签订日期'] = qdtime
    # 土地使用权人
    tdsyq = items.find(
        'span', id="mainModuleContainer_1855_1856_ctl00_ctl00_p1_f1_r23_c2_ctrl").get_text()
    info['土地使用权人'] = tdsyq
    # 用唯一值的电子监管号当key, 所需信息当value的字典
    Key_ID = items.find(
        'span', id="mainModuleContainer_1855_1856_ctl00_ctl00_p1_f1_r1_c4_ctrl").get_text()
    info['电子监管号'] = Key_ID
    #r.sadd("zlist1",info)
    print("信息:",info['行政区'],info['项目名称'],info['项目位置'],info['面积'],info['土地用途'],info['约定开工时间'],info['约定竣工时间'],info['合同签订日期'],info['土地使用权人'],info['电子监管号'])
    return info
def checkRedis(sleepCounter, headers):  # 从redis读,并解析页面
                                        # 如果redis中暂无数据,等待。等待时间超过100秒后退出程序。
    book = xlwt.Workbook()
    sheet1 = book.add_sheet('sheet1')
    row0 = ["行政区","项目名称","项目位置","面积","土地用途","约定开工时间","约定竣工时间","合同签订日期","土地使用权人","电子监管号"]
    #写第一行
    for i in range(0,len(row0)):
        sheet1.write(0,i,row0[i])
    rowNo = 0
    while 1:
        if r.scard('mylist2') != 0:
            url = r.spop('mylist2')
            print("二级URL:",url)
            info=get_info(url, headers)
            newRow = [info['行政区'],info['项目名称'],info['项目位置'],info['面积'],info['土地用途'],info['约定开工时间'],info['约定竣工时间'],info['合同签订日期'],info['土地使用权人'],info['电子监管号']]
            rowNo = rowNo+1
            for i in range(0,len(newRow)):
                sheet1.write(rowNo,i,newRow[i])
            sleepTime = random.random() * 5
            print(time.strftime("%Y%m%d%H%M%S", time.localtime()),"休眠",sleepTime,"秒")
            time.sleep(sleepTime)
            print(time.strftime("%Y%m%d%H%M%S", time.localtime()),"休眠结束")
            #parse(url, headers)
        elif sleepCounter < 1:
            print('waiting...' + str(sleepCounter))
            sleepCounter += 1
            time.sleep(1)
            break
        else:
            print('quit')
            break
    book.save("result-"+str(rowNo)+"-"+time.strftime("%Y%m%d%H%M%S", time.localtime())+".xls")
def getCookie():
    chrome_options = webdriver.ChromeOptions()
    #options.add_argument('--proxy-server=http://' + proxy)
    chrome_options.add_argument("--headless")
    driver = webdriver.Chrome(options=chrome_options)  # 打开chrome_headless浏览器
    driver.get('http://www.landchina.com/default.aspx?tabid=263&ComName=default')  # 打开界面
    time.sleep(5)
    cookie = driver.get_cookies()
    str1 = list(cookie)
    strnew = ''
    for i in range(0, len(str1)):
        strnew = strnew + str1[i]['name'] + '=' + str1[i]['value'] + ';'
    print(strnew)
    driver.quit()
    return strnew
def createHeaders(cookie):
    headers = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7',
        'Cache-Control': 'max-age=0',
        'Connection': 'keep-alive',
        'Content-Type': 'application/x-www-form-urlencoded',
        'Host': 'www.landchina.com',
        'Origin': 'http://www.landchina.com',
        'Upgrade-Insecure-Requests': '1',
        'Cookie': cookie,
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'
    }
    return headers
#@retry(tries=5, delay=2) 出错重试5次,延迟2秒
def doTheJob():
    cookie = getCookie()
    headers = createHeaders(cookie)
    checkRedis(0, headers=headers)
doTheJob()

完工。

你可能感兴趣的:(landchina数据爬取(2020.1.6))