常见的爬取请求有node-fetch、axios或got
Common crawl request with node-fetch, axios or got
我正在尝试将我的 C# 通用抓取代码移植到 Node.js,但在从 HTML 获取单个页面时,所有 HTTP 库(node-fetch、got 的 axios)都出现错误共同抓取 S3 存档。
const offset = 994879995;
const length = 27549;
const offsetEnd = offset + length + 1;
const url = `https://data.commoncrawl.org/crawl-data/CC-MAIN-2018-43/segments/1539583511703.70/warc/CC-MAIN-20181018042951-20181018064451-00103.warc.gz`;
const response = await fetch(
url, //'https://httpbin.org/get',
{
method: "GET",
timeout: 10000,
compress: true,
headers: {
Range: `bytes=${offset}-${offsetEnd}"`,
'Accept-Encoding': 'gzip'
},
}
);
console.log(`status`, response.status);
console.log(`headers`, response.headers);
console.log(await response.text());
状态为 200
,但包的 none 能够读取正文 gzip 正文。
虽然我的 C# 代码可以正常读取正文作为字节数组并将其解压缩。
下面的代码将获取单个 WARC 记录并提取 HTML 有效负载。所有状态行和 headers(WARC 记录的 HTTP 提取、WARC 记录 header、WARC 记录 HTTP header)以及 HTML 有效负载都会被记录下来。更改了以下几点:
JS请求中的范围header包含多余的引号。这实际上导致请求的不是单个 WARC 记录,而是完整的 1+ GiB WARC 文件。
- 查看响应状态代码:200 但应为 206“部分内容”
- 还有“content-length”响应 header
- 对于获取 1 GiB,10 秒的超时时间可能太短
结束偏移量应该是offset + length - 1
(而不是... + 1
):在最坏的情况下,2个额外的字节会导致gzip解压器抛出异常
因为 WARC 记录已经 gzip-compressed 请求任何 HTTP-level 压缩没有意义
gzipped WARC 记录需要解压缩和解析。两者都是由 warcio 完成的 - 看看这个模块的优秀文档。
const fetch = require("node-fetch");
const warcio = require("warcio");
class WarcRecordFetcher {
async run() {
const offset = 994879995;
const length = 27549;
const offsetEnd = offset + length - 1;
const url = `https://data.commoncrawl.org/crawl-data/CC-MAIN-2018-43/segments/1539583511703.70/warc/CC-MAIN-20181018042951-20181018064451-00103.warc.gz`;
const response = await fetch(
url, //'https://httpbin.org/get',
{
method: "GET",
timeout: 10000,
headers: {
Range: `bytes=${offset}-${offsetEnd}`
},
}
);
console.log(`status`, response.status);
console.log(`headers`, response.headers);
const warcParser = new warcio.WARCParser(response.body);
const warcRecord = await warcParser.parse();
console.log(warcRecord.warcHeaders.statusline);
console.log(warcRecord.warcHeaders.headers);
console.log(warcRecord.httpHeaders.statusline);
console.log(warcRecord.httpHeaders.headers);
const warcPayload = await warcRecord.contentText();
console.log(warcPayload)
}
}
new WarcRecordFetcher().run();
我正在尝试将我的 C# 通用抓取代码移植到 Node.js,但在从 HTML 获取单个页面时,所有 HTTP 库(node-fetch、got 的 axios)都出现错误共同抓取 S3 存档。
const offset = 994879995;
const length = 27549;
const offsetEnd = offset + length + 1;
const url = `https://data.commoncrawl.org/crawl-data/CC-MAIN-2018-43/segments/1539583511703.70/warc/CC-MAIN-20181018042951-20181018064451-00103.warc.gz`;
const response = await fetch(
url, //'https://httpbin.org/get',
{
method: "GET",
timeout: 10000,
compress: true,
headers: {
Range: `bytes=${offset}-${offsetEnd}"`,
'Accept-Encoding': 'gzip'
},
}
);
console.log(`status`, response.status);
console.log(`headers`, response.headers);
console.log(await response.text());
状态为 200
,但包的 none 能够读取正文 gzip 正文。
虽然我的 C# 代码可以正常读取正文作为字节数组并将其解压缩。
下面的代码将获取单个 WARC 记录并提取 HTML 有效负载。所有状态行和 headers(WARC 记录的 HTTP 提取、WARC 记录 header、WARC 记录 HTTP header)以及 HTML 有效负载都会被记录下来。更改了以下几点:
JS请求中的范围header包含多余的引号。这实际上导致请求的不是单个 WARC 记录,而是完整的 1+ GiB WARC 文件。
- 查看响应状态代码:200 但应为 206“部分内容”
- 还有“content-length”响应 header
- 对于获取 1 GiB,10 秒的超时时间可能太短
结束偏移量应该是
offset + length - 1
(而不是... + 1
):在最坏的情况下,2个额外的字节会导致gzip解压器抛出异常因为 WARC 记录已经 gzip-compressed 请求任何 HTTP-level 压缩没有意义
gzipped WARC 记录需要解压缩和解析。两者都是由 warcio 完成的 - 看看这个模块的优秀文档。
const fetch = require("node-fetch");
const warcio = require("warcio");
class WarcRecordFetcher {
async run() {
const offset = 994879995;
const length = 27549;
const offsetEnd = offset + length - 1;
const url = `https://data.commoncrawl.org/crawl-data/CC-MAIN-2018-43/segments/1539583511703.70/warc/CC-MAIN-20181018042951-20181018064451-00103.warc.gz`;
const response = await fetch(
url, //'https://httpbin.org/get',
{
method: "GET",
timeout: 10000,
headers: {
Range: `bytes=${offset}-${offsetEnd}`
},
}
);
console.log(`status`, response.status);
console.log(`headers`, response.headers);
const warcParser = new warcio.WARCParser(response.body);
const warcRecord = await warcParser.parse();
console.log(warcRecord.warcHeaders.statusline);
console.log(warcRecord.warcHeaders.headers);
console.log(warcRecord.httpHeaders.statusline);
console.log(warcRecord.httpHeaders.headers);
const warcPayload = await warcRecord.contentText();
console.log(warcPayload)
}
}
new WarcRecordFetcher().run();