Fiddler and web traffic:
I inspected the web traffic whilst on this page using fiddler. I saw that there was a GET request made for the data of interest. N.B. I went with the default info on the page. Making changes may result in a POST request which will follow broadly the same approach but would require a parameter based POST request with any required Header information and the like.
Fiddler output:

JSON response:
This GET request returned a JSON string containing all the CALLS/PUTS.
JSON sample:

JSON  preview:

So I replicated this GET request using XMLHTTP request and then used JSONConverter to handle the JSON string returned*. 
*Note:  After downloading JSONConverter.bas and adding to project you must add a reference to Microsoft Scripting Runtime via VBE > Tools > References
The object generated by Set JSON = JsonConverter.ParseJson(sResponse) is a dictionary as denoted by the leading "{".
JSON object handling:
I used JSONConverter to handle accessing information from the JSON Object.
The initial dictionary has keys of "quoteDelayed","quoteDelay","tradeDate","optionContractQuotes","underlyingFutureContractQuotes","empty".
Reviewing the webpage:
The following shows the webpage headers and first data row.

I am looking in the JSON structure for information on Calls, Strike Price and Puts. This info appears to be under key "optionContractQuotes"
Required information:

So, we can re-assign JSON to this part of the original JSON (we could have jumped straight to this but I thought it might help to explain) with:
Set JSON = JSON("optionContractQuotes")
Collection of dictionaries:
A quick inspection of the new JSON structure tells me this will be a collection of dictionaries. The "[" tells me I have a collection and the following "{", as before, tells me I then have dictionaries, as "{" is repeated, inside.

A closer examination shows me that these dictionaries have keys of "strikePrice","strikeRank","put","call","underlyingFutureContract". 
The info we really care about:
We care about keys "strikePrice", "put" and "call". "strikePrice" key has primitive string value e.g.
"strikePrice": "140.0",
"put" and "call" keys have associated dictionaries. Remember the "{"? 
Example keys from call dictionary object:

What we can see from the above, is that the keys of the dictionaries "put" and "call" correspond to the original source headers, and the values correspond to the rows of information we saw originally in the webpage source table.
Caveat: There are slight differences between the webpage headers and the associated JSON headers (there is also more info in the JSON...), so mapped headers are used for accessing the JSON structure to then write out to the appropriate column in the sheet:
jsonHeaders = Array("updated", "highLowLimits", "volume", "high", "low", "priorSettle", "change", "last")
Why bother?
The above analysis of the JSON structure has led us to a point where we now know:
- Where the items are located that we are interested in
- How these items would map to our output table (remember the point raised about headers and row data?).
Writing to the sheet:
To make things easier I am going to actually hard code the headers for "calls" and "puts" in the sheet with:
headers = Array("Updated", "Hi / Low Limit", "Volume", "High", "Low", "Prior Settle", "Change", "Last", "Strike Price", "Last", "Change", "Prior Settle", "Low", "High", "Volume", "Hi / Low Limit", "Updated")
I can then write those out in one go as my table headers with:
.Cells(1, 1).Resize(1, UBound(headers) + 1) = headers
I know that my rows are "call", "Strike Price", "put". And that "put" headers are the same headers as "call" headers, but in reverse order:

This handy observation means, when I am looping each dictionary in the collection, which is effectively a row of information to population the table with; I can pass each dictionary to a helper sub, WriteToSheet. This helper sub uses the keys of interest to access the dictionary values and write them to the sheet. If "strikePrice" the associated value can be written direct to column 9, the middle of  our table. Otherwise, if it is either "call" or "put", we can loop the jsonHeaders array to access the required inner dictionary information. Remember that "call" and "put" are dictionaries in their own right, whereas "strikePrice" was a primitive string.
To save looping the headers twice, once for "put" and once for "call", I shorthand the whole thing into a single loop:
For i = LBound(jsonHeaders) To UBound(jsonHeaders) '<==Dictionaries
    .Cells(rowCounter, i + 1).Value = inputDict("call")(jsonHeaders(i))
    .Cells(rowCounter, 17 - i).Value = inputDict("put")(jsonHeaders(i))
Next i
And bish, bash, bosh we have our table in the sheet.
Sample view of webpage:

View of code output:

VBA:
Option Explicit
Public Sub GetCrudeOilOptionQuotes()
    Dim sResponse As String, JSON As Object, headers(), jsonHeaders(), ws As Worksheet
    headers = Array("Updated", "Hi / Low Limit", "Volume", "High", "Low", "Prior Settle", "Change", "Last", "Strike Price", "Last", "Change", "Prior Settle", "Low", "High", "Volume", "Hi / Low Limit", "Updated")
    jsonHeaders = Array("updated", "highLowLimits", "volume", "high", "low", "priorSettle", "change", "last") '<== JSON headers vary from visible headers on page slightly
    'Ignored headers  open,close,highLimit,lowLimit
    Set ws = ActiveSheet
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "https://www.cmegroup.com/CmeWS/mvc/Quotes/Option/769/G/Q8/ATM?optionExpiration=190-M6&strikeRange=ATM&optionProductId=769&pageSize=500&_=1530436274974", False
        .send
        sResponse = StrConv(.responseBody, vbUnicode)
    End With
    Set JSON = JsonConverter.ParseJson(sResponse) 'Returns a dictionary
    Dim i As Long, rowCounter As Long
    Set JSON = JSON("optionContractQuotes")      '<==Collection of dictionaries
    rowCounter = 1
    With ws
        .UsedRange.ClearContents
        .Cells(1, 1).Resize(1, UBound(headers) + 1) = headers
    End With
    For i = 1 To JSON.Count                      'Loop all the dictionaries to empty info into rows and columns of sheet
        rowCounter = rowCounter + 1
        WriteToSheet JSON(i), jsonHeaders, rowCounter, ws
    Next i
End Sub
Public Sub WriteToSheet(ByVal inputDict As Object, ByVal jsonHeaders As Variant, ByVal rowCounter As Long, ByVal ws As Worksheet)
    Application.ScreenUpdating = False
    Dim key As Variant, i As Long
    With ws
        .Cells(rowCounter, 9).Value = inputDict("strikePrice") '<==literal string
        For i = LBound(jsonHeaders) To UBound(jsonHeaders) '<==Dictionaries
            .Cells(rowCounter, i + 1).Value = inputDict("call")(jsonHeaders(i))
            .Cells(rowCounter, 17 - i).Value = inputDict("put")(jsonHeaders(i))
        Next i
    End With
    Application.ScreenUpdating = True
End Sub