1

我试图使用 GuzzleHTTP 6 进行网络抓取,到目前为止,我无法在响应正文中找到混乱编码的解决方案。

假设我想解析网页,它以多种不同的语言返回数据。

客户端初始化

public function __construct() {
    $this->dataClient = new Client(['base_uri' => 'http://somewebsite.org/{language_code}']);
}

使用数据客户端

$request = $this->dataClient->get('/endpoint/' . $data_query . '/');
$response = $request->getBody()->__toString();
$decoded = json_decode($response, true);
foreach ($decoded as $index => $data) {
    $decoded[$index] = str_replace(['<option', '>', '</option>'], '', $data);
}
return $decoded;

问题:

  1. 如果文本是英文,响应看起来几乎没问题,除了一些字符被弄乱了

    操纵,有

代替

manipulation, there's
  1. 如果我试图获取任何其他语言的数据,那就是我得到的(俄语数据)

    ↓;↓;°; Ð;¿;Ð;µ;Ñ;€Ð;²;Ñ;‹Ð;¹; Ð;²;Ð

代替

На первый взгляд

问题是,如果您查看网站,一切都很好,但如果您尝试抓取它,您将面临这些问题。到目前为止,我无法找到问题的根源,utf8_decode 或 iconv 都无法帮助我解决问题。
任何解决方案都非常受欢迎!

所以,这里有一个小更新 这是解析函数:

public function processData($data_query) {
    $request = $this->dataClient->get('/endpoint/' . $data_query . '/');
    $response = $request->getBody()->__toString();
    // echo $response; - Everything is fine, no encoding problems
    // return $response; - Encoding problems
    $decoded = json_decode($response, true);
    // return $decoded; - Encoding problems
    foreach ($decoded as $index => $data) {
        $decoded[$index] = str_replace(['<option', '>', '</option>'], '', $data);
    }
    return $decoded; - Encoding Problems
}

原始响应标头

{
    Date: [
        "Wed, 08 Jun 2016 01:45:30 GMT"
    ],
    Server: [
        "Apache"
    ],
    X-Frame-Options: [
        "SAMEORIGIN"
    ],
    Retry-After: [
        "600"
    ],
    Content-Language: [
        "en-GB"
    ],
    Vary: [
        "Accept-Encoding"
    ],
    Transfer-Encoding: [
        "chunked"
    ],
    Content-Type: [
        "text/html;charset=UTF-8"
    ]
}
4

2 回答 2

2

我有一个类似的案例(使用 Guzzle 加载 XML 并使用 SimpleXML 解析),但我知道源在 ISO-8559-1 中,但 SimpleXML 解析结果的输出被打乱了。我尝试了很多方法,只有这个解决了_:

$attribute = mb_convert_encoding((string) $attribute, 'ISO-8859-1', 'UTF-8');

该属性是一些 XML 节点值。我只是将已知编码转换为我想要的编码。希望可以帮助一些人...

于 2018-04-06T11:04:23.837 回答
0

阅读此处发布的较旧的 SO 响应:Can Goutte/Guzzle 被强制进入 UTF-8 模式吗?. 是的,它提到了使用utf8_decode()但也与 Guzzle 的分叉结合使用。看看 Guzzle 的问题跟踪器,它是否有与您的问题相似的问题?如果是这样,请对其发表评论以查看核心开发人员是否会修复它。上面的 SO 帖子已有 3 年历史,如果问题如此普遍,如果仍然需要黑客和分叉,我会感到惊讶。

也许它被修复,您现在需要确保抓取的页面本身正在发送正确的编码标头。请注意,响应标头有优先顺序。我相信最重要的是网络服务器,然后是 DOM 本身,如果这些标头没有从网络服务器的响应中发送或省略的话。但是请检查一下,因为我不是 100%。

于 2016-06-08T01:23:08.857 回答