\xe2\x94\x80 — это текстовое представление байт в Питоне. Байты - перевод из строки:
>>> '\u2500'.encode()
b'\xe2\x94\x80'
то есть байты: 226, 148, 128 записаны, используя экранирующие последовательности ascii символов \ x h h: \xe2, \x94, \x80 (т.к. 22610 = e216, 14810 = 9416, 12810 = 8016).
─ (U+2500) символ кодируется в utf-8 кодировке последовательностью октетов: 226, 148, 128.
Вы их видите как \xe2\x94\x80 из-за str(text.encode()) в коде в вопросе (это ошибка, не следует так делать). Текстовое представление байт (repr) полезно при отладке. На диск следует писать либо сами байты (файл должен быть открыт в двоичном режиме: 'wb') как показано в @gil9red ответе, либо использовать текстовый интерфейс ('w' режим и подходящий для документа encoding параметр).
Чтобы гарантировать, что html записан на диск в utf-8 кодировке в самосогласованном виде вне зависимости в какой кодировке сайт возвращает html, можно BeautifulSoup использовать.
В вашем случае, сайт уже html в виде utf-8 возвращает и в самом содержимом <meta элемент c Content-Type это подтверждает, поэтому достаточно Path('test.html').write_bytes(r.content) вариант использовать.
.write(r.text)и всё, зачем всё усложнять-то – andreymal Dec 28 '17 at 23:36write(r.text)может несогласованное содержимое создать:<meta charsetможет одно говорить, а фактическая кодировка файла, определяемаяlocale.getpreferredencoding()другое. Лучше как есть content в 'wb' режиме сохранять, если кодировка в html указана. Поэтому beautifulsoup4 умеет переписывать соответсвующие элементы (для случаев когда хочется поменять кодировку или когда кодировка в http заголовках, а не самом содержимом прописана) в prettify(), encode() методах — в итоге самосогласованное содержимое на диске: html записан на диск в указанной в нём кодировке. – jfs Dec 29 '17 at 06:52