Как получить html-страницу веб-сайта с использованием TCP-сокета? [Дубликат]

Самый простой способ - создать список возможных чисел (1..20 или что-то еще), а затем перетасовать их с помощью Collections.shuffle. Тогда просто возьмите все, что захотите. Это здорово, если ваш диапазон равен количеству элементов, которые вам нужны в конце (например, для перетасовки колоды карт).

Это не работает так хорошо, если вы хотите (скажем) 10 случайных элементов в диапазоне 1,10,000 - вы в конечном итоге делаете много работы без необходимости. В этот момент, вероятно, лучше сохранить набор значений, которые вы создали до сих пор, и просто продолжать генерировать числа в цикле до тех пор, пока следующий еще не будет присутствовать:

if (max < numbersNeeded)
{
    throw new IllegalArgumentException("Can't ask for more numbers than are available");
}
Random rng = new Random(); // Ideally just create one instance globally
// Note: use LinkedHashSet to maintain insertion order
Set<Integer> generated = new LinkedHashSet<Integer>();
while (generated.size() < numbersNeeded)
{
    Integer next = rng.nextInt(max) + 1;
    // As we're adding to a set, this will automatically do a containment check
    generated.add(next);
}

Будьте осторожны с установленным выбором, хотя - я очень сознательно использовал LinkedHashSet, поскольку он поддерживает порядок вставки, о котором мы здесь заботимся.

Еще один вариант - always сделать прогресс, путем сокращения диапазона каждый раз и компенсации существующих значений. Например, предположим, что вам нужно 3 значения в диапазоне 0..9. На первой итерации вы должны сгенерировать любое число в диапазоне 0..9 - допустим, вы создаете 4.

. На второй итерации вы должны сгенерировать число в диапазоне 0..8 , Если сгенерированное число меньше 4, вы сохраните его как есть ... иначе вы добавите его в него. Это дает вам диапазон результатов 0..9 без 4. Предположим, что мы получаем 7.

На третьей итерации вы должны сгенерировать число в диапазоне 0..7. Если сгенерированное число меньше 4, вы сохраните его как есть. Если это 4 или 5, вы должны добавить один. Если это 6 или 7, вы бы добавили два. Таким образом, диапазон результатов равен 0..9 без 4 или 6.

3
задан james smith 10 December 2015 в 02:15
поделиться

4 ответа

Вы забыли отправить пустую строку после строки запроса:

s.sendall("GET / HTTP/1.1\r\n\r\n")

Кроме того, HTTP 1.1 указывает, что вы должны добавить поле заголовка Host, как описано в разделе Host в HTTP 1.1 RFC .

s.sendall("GET / HTTP/1.1\r\nHost: www.cnn.com\r\n\r\n")
8
ответ дан Takis 16 August 2018 в 00:06
поделиться

Извините, чтобы тратить время на все. Я нашел это решение здесь в Stack Overflow (просто взял некоторые изменения в моем поиске Google, чтобы найти)

import socket
request = b"GET / HTTP/1.1\nHost: www.cnn.com\n\n"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("cnn.com", 80))
s.send(request)
result = s.recv(10000)
while (len(result) > 0):
    print(result)
    result = s.recv(10000)

И все ответы были правильными, а также о завершении \r\n\r\n однако те возвратили статусы 301. Кажется, это решение как-то следует за перенаправлением? В любом случае, эти решения работали для меня

2
ответ дан Community 16 August 2018 в 00:06
поделиться
  • 1
    Этот код дает ответ 302. Он не следует за перенаправлением. Вам нужно обрабатывать перенаправления для школьного проекта? – mhawke 10 December 2015 в 02:37

Попробуйте заменить эту строку:

s.sendall("GET / HTTP/1.1\r\n")

с:

s.sendall("GET / HTTP/1.1\r\n\r\n")
                             ^^^^

Кроме того, я думаю, вам нужно заменить s.close на s.close(), поскольку это функция.

1
ответ дан Kevin Guan 16 August 2018 в 00:06
поделиться

Ваш код почти прав, но вам нужно отправить 2 последовательности \r\n, чтобы удовлетворить HTTP-протокол.

Правильный запрос GET будет выглядеть следующим образом (примечание 2 строки):

GET / HTTP/1.1

Итак, ваш код должен быть:

s.sendall('GET / HTTP/1.1\r\n\r\n')

. Кроме того, для действительных запросов HTTP 1.1 требуются дополнительные заголовки, такие как Host:. Вам нужно добавить их в свой запрос, примерно так:

s.sendall('''GET / HTTP/1.1
Host: cnn.com

''')
5
ответ дан mhawke 16 August 2018 в 00:06
поделиться
  • 1
    Это отвечает на мои вопросы и было первым, поэтому я предполагаю, что сделаю это правильно. Для других см. Также мой собственный ответ – james smith 10 December 2015 в 02:25
  • 2
    @jamessmith: вы должны выбрать лучший ответ, а не первый ответ. Во всяком случае, я думаю, что Такис ​​ответил первым :) – mhawke 10 December 2015 в 02:42
Другие вопросы по тегам:

Похожие вопросы: