teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

8

修正

2016/08/27 15:46

投稿

dlrowolleh
dlrowolleh

スコア120

title CHANGED
@@ -1,1 +1,1 @@
1
- C言語でHTTP通信でHTMLファイルを取得し、保存することは可能でしょうか?
1
+ C言語でHTTP通信でHTMLファイルを取得し、保存することは可能でしょうか?C言語でクローリングがしたいです。
body CHANGED
@@ -1,7 +1,7 @@
1
1
  初心者です。
2
2
  よろしくお願いいいたします。
3
3
 
4
- 早速ですが、私はC言語でWebスクレイピング・Webローリングをしたいと思っております。
4
+ 早速ですが、私はC言語でWebスクレイピング・Webローリングをしたいと思っております。
5
5
 
6
6
 
7
7
  WebスクレイピングやWebクローリングについて自分自身、調べたりしたところ、PHPやpython、perl、ruby、shellscriptなどのスクリプト言語を用いるのが普通のようでした。

7

追記

2016/08/27 15:46

投稿

dlrowolleh
dlrowolleh

スコア120

title CHANGED
File without changes
body CHANGED
@@ -270,4 +270,42 @@
270
270
  よろしくお願いします。
271
271
 
272
272
  また、コンパイル時に
273
- errorやwarningがあった場合、皆様はどのように解決するときのヒントや初心者が犯しやすいミスがあれば教えていただけましたら幸いです。
273
+ errorやwarningがあった場合、皆様はどのように解決するときのヒントや初心者が犯しやすいミスがあれば教えていただけましたら幸いです。
274
+
275
+ ###追記(2016/08/23)
276
+
277
+ 実行結果がうまくいっていないような気がします。
278
+ ---
279
+
280
+ 参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://qiita.com/edo_m18/items/cef278d0c14d1371db3b)を実行してみたのですが、以下のような実行結果が得られました。
281
+ なんだか少し違うような気がするのですが、
282
+ 実行結果がうまくいっているのかの私では判断ができません。
283
+ 自信がなく、よくわからず質問してしまって申し訳ありませんが、
284
+ この実行結果で正しいのでしょうか?
285
+ ```
286
+ $ ./a.out
287
+ http://css-eblog.com/P を取得します。 // http://css-eblog.com/Pを取得しているところが少し疑問です。
288
+ // http://css-eblog.comになるのではと思いますがどうなのでしょうか…?
289
+
290
+ HTTP/1.1 400 Bad Request
291
+ Date: Sat, 27 Aug 2016 15:23:02 GMT
292
+ Server: Apache/2.2.31
293
+ Content-Length: 226
294
+ Connection: close
295
+ Content-Type: text/html; charset=iso-8859-1
296
+
297
+ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
298
+ <html><head>
299
+ <title>400 Bad Request</title> // http://css-eblog.com/Pだからそんなページはないと言われてしまう?
300
+ // http://css-eblog.comだったら検索できましたが
301
+ // http://css-eblog.com/Pでは検索できませんでした。
302
+ </head><body>
303
+ <h1>Bad Request</h1>
304
+ <p>Your browser sent a request that this server could not understand.<br />
305
+ </p>
306
+ </body></html>
307
+ ```
308
+ 自信がなく、よくわからず質問してしまい、恐縮ですが、
309
+ http://css-eblog.com/P になってしまう原因は何でしょうか?
310
+ どうすれば http://css-eblog.com になるでしょうか?
311
+ 何卒、よろしくお願いします。

6

追記

2016/08/27 15:44

投稿

dlrowolleh
dlrowolleh

スコア120

title CHANGED
File without changes
body CHANGED
@@ -31,7 +31,7 @@
31
31
  よろしくお願いいたします。
32
32
 
33
33
  ---
34
- ###追記(07/27)
34
+ ###追記(07/27)【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
35
35
  皆様のアドバイスをもとにプログラムを書いています。
36
36
  エラーの意味が分からず困っています。
37
37
  写し間違いだと思うのですが、どこを間違えているのか、エラーの描いてあることがよく分かりません。
@@ -220,7 +220,7 @@
220
220
  169 }
221
221
  170 }
222
222
  ```
223
- ###エラーコード
223
+ ###エラーコード【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
224
224
  > $ gcc -o syakyou syakyou.c
225
225
  syakyou.c: In function ‘main’:
226
226
  syakyou.c:45:21: error: ‘url’ undeclared (first use in this function)
@@ -235,20 +235,20 @@
235
235
  p = strchr(url1->host, ':');
236
236
  ^
237
237
 
238
- ###試したこと
238
+ ###試したこと【vimdiff syakyou.c othon.cで解決いたしました】
239
239
  otehon.cはコピペしたテキストプログラム
240
240
  syakyou.cは見ながら写したプログラム
241
241
  > $ diff syakyou.c otehon.c
242
242
 
243
- ###結果
243
+ ###結果【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
244
244
  otehon.cはインデントが空白
245
245
  syakyou.cはインデントがタブ
246
246
  のため、差分の量が多過ぎて見分けがつかず、お手上げです。
247
247
  重ね重ね申し訳ありません。
248
248
 
249
249
  ---
250
- ###追記(08/08)
250
+ ###追記(08/08)【打ち間違いに気がつき解決いたしました】
251
- ###warningが出て困っています。どなたか教えていただけないでしょうか
251
+ ###warningが出て困っています。どなたか教えていただけないでしょうか【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
252
252
  > $ gcc syakyou.c
253
253
  syakyou.c: In function ‘main’:
254
254
  syakyou.c:83:20: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘char *’ [-Wformat=]
@@ -258,7 +258,7 @@
258
258
  これはどういった意味なのでしょうか?
259
259
  char型なのに %d にしているというということでしょうか?
260
260
 
261
- ###試したこと
261
+ ###試したこと【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
262
262
 
263
263
  Chironian様のアドバイスを元に
264
264
  ```c

5

追記

2016/08/27 15:14

投稿

dlrowolleh
dlrowolleh

スコア120

title CHANGED
File without changes
body CHANGED
@@ -244,4 +244,30 @@
244
244
  otehon.cはインデントが空白
245
245
  syakyou.cはインデントがタブ
246
246
  のため、差分の量が多過ぎて見分けがつかず、お手上げです。
247
- 重ね重ね申し訳ありません。
247
+ 重ね重ね申し訳ありません。
248
+
249
+ ---
250
+ ###追記(08/08)
251
+ ###warningが出て困っています。どなたか教えていただけないでしょうか
252
+ > $ gcc syakyou.c
253
+ syakyou.c: In function ‘main’:
254
+ syakyou.c:83:20: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘char *’ [-Wformat=]
255
+ sprintf(send_buf, "Host: %s:%d\r\n", url.host, url.path); ^
256
+
257
+ です。
258
+ これはどういった意味なのでしょうか?
259
+ char型なのに %d にしているというということでしょうか?
260
+
261
+ ###試したこと
262
+
263
+ Chironian様のアドバイスを元に
264
+ ```c
265
+ 58 hints.ai_socktyoe = AF_INET; を
266
+ 58 hints.ai_family = AF_INET; に打ち直しました。
267
+ url1 を
268
+ url に直しました。
269
+ ```
270
+ よろしくお願いします。
271
+
272
+ また、コンパイル時に
273
+ errorやwarningがあった場合、皆様はどのように解決するときのヒントや初心者が犯しやすいミスがあれば教えていただけましたら幸いです。

4

更新

2016/08/08 06:32

投稿

dlrowolleh
dlrowolleh

スコア120

title CHANGED
File without changes
body CHANGED
@@ -243,4 +243,5 @@
243
243
  ###結果
244
244
  otehon.cはインデントが空白
245
245
  syakyou.cはインデントがタブ
246
- のため、差分の量が多過ぎて見分けがつかず、お手上げです。
246
+ のため、差分の量が多過ぎて見分けがつかず、お手上げです。
247
+ 重ね重ね申し訳ありません。

3

更新

2016/07/27 05:58

投稿

dlrowolleh
dlrowolleh

スコア120

title CHANGED
File without changes
body CHANGED
@@ -45,7 +45,7 @@
45
45
 
46
46
  よろしくお願いいたします。
47
47
 
48
- 参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://http://qiita.com/edo_m18/items/cef278d0c14d1371db3b)
48
+ 参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://qiita.com/edo_m18/items/cef278d0c14d1371db3b)
49
49
 
50
50
  ```C
51
51
  //syakyou.c

2

追記

2016/07/27 05:56

投稿

dlrowolleh
dlrowolleh

スコア120

title CHANGED
File without changes
body CHANGED
@@ -28,4 +28,219 @@
28
28
 
29
29
 
30
30
  どうかお助けください。
31
- よろしくお願いいたします。
31
+ よろしくお願いいたします。
32
+
33
+ ---
34
+ ###追記(07/27)
35
+ 皆様のアドバイスをもとにプログラムを書いています。
36
+ エラーの意味が分からず困っています。
37
+ 写し間違いだと思うのですが、どこを間違えているのか、エラーの描いてあることがよく分かりません。
38
+ どなたか解説していただけませか。
39
+
40
+ そもそもコードが公開されているのであれば、それをコピーすればいいのかもしれませんが、少しでも理解して身につけたいと思い、コピペはせず、見ながら打ち込むようにしています。
41
+
42
+ 効率が最悪かもしれませんが、親切な方がいらっしゃいましたら、このひよっこに暖かい手を差し伸べていただけないでしょうか。
43
+
44
+ また、効率の良いやり方・勉強法等をご存知の方がいらっしゃいましたら、併せて教えていただけましたら幸いです。
45
+
46
+ よろしくお願いいたします。
47
+
48
+ 参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://http://qiita.com/edo_m18/items/cef278d0c14d1371db3b)
49
+
50
+ ```C
51
+ //syakyou.c
52
+ 1 #include <stdio.h>
53
+ 2 #include <string.h>
54
+ 3 #include <stdlib.h>
55
+ 4 #include <sys/types.h>
56
+ 5 #include <netdb.h>
57
+ 6 #include <netinet/in.h>
58
+ 7 #include <sys/param.h>
59
+ 8 #include <unistd.h>
60
+ 9
61
+ 10 #define BUF_LEN 256
62
+ 11
63
+ 12 struct URL {
64
+ 13 char host[BUF_LEN];
65
+ 14 char path[BUF_LEN];
66
+ 15 char query[BUF_LEN];
67
+ 16 char fragment[BUF_LEN];
68
+ 17 unsigned short port;
69
+ 18 };
70
+ 19
71
+ 20 /**
72
+ 21 * @param urlStr URLテキスト
73
+ 22 */
74
+ 23 void parseURL(const char *urlStr, struct URL *url, char **error);
75
+ 24
76
+ 25 int main(int argc, char **argv) {
77
+ 26
78
+ 27 //ソケットのためのファイルディスクリプタ
79
+ 28 int s;
80
+ 29
81
+ 30 //IPアドレスの解決
82
+ 31 struct addrinfo hints, *res;
83
+ 32 struct in_addr addr;
84
+ 33 int err;
85
+ 34
86
+ 35 //サーバに送るHTTPプロトコル用バッファ
87
+ 36 char send_buf[BUF_LEN];
88
+ 37
89
+ 38 struct URL url1 = {
90
+ 39 "css-eblog.com","/",80
91
+ 40 };
92
+ 41
93
+ 42 //URLが指定されていたら
94
+ 43 if(argc>1){
95
+ 44 char *error = NULL;
96
+ 45 parseURL(argv[1],&url,&error);
97
+ 46
98
+ 47 if(error){
99
+ 48 printf("%s/n",error);
100
+ 49 return 1;
101
+ 50 }
102
+ 51 }
103
+ 52
104
+ 53 printf("http://%s%s%sを取得します。\n\n", url.host, url1.path, url.query);
105
+ 54
106
+ 55 //0クリア
107
+ 56 memset(&hints, 0, sizeof(hints));
108
+ 57 hints.ai_socktype = SOCK_STREAM;
109
+ 58 hints.ai_socktyoe = AF_INET;
110
+ 59
111
+ 60 char *serviceType = "http";
112
+ 61
113
+ 62 if((err = getaddrinfo(url.host, serviceType, &hints, &res)) != 0) {
114
+ 63 printf("error %d\n", err);
115
+ 64 return 1;
116
+ 65 }
117
+ 66
118
+ 67 //ソケット生成
119
+ 68 if((s = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
120
+ 69 fprintf(stderr, "ソケットの作成に失敗しました。\n");
121
+ 70 return 1;
122
+ 71 }
123
+ 72
124
+ 73 //サーバに接続
125
+ 74 if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
126
+ 75 fprintf(stderr, "connectに失敗しました。\n");
127
+ 76 return 1;
128
+ 77 }
129
+ 78
130
+ 79 //HTTPプロトコルの開始 &サーバに送信
131
+ 80 sprintf(send_buf, "GET %s%s HTTP/1.0\r\n", url.path, url.query);
132
+ 81 write(s, send_buf, strlen(send_buf));
133
+ 82
134
+ 83 sprintf(send_buf, "Host: %s:%d\r\n", url.host, url.path);
135
+ 84 write(s, send_buf, strlen(send_buf));
136
+ 85
137
+ 86 sprintf(send_buf, "\r\n");
138
+ 87 write(s, send_buf, strlen(send_buf));
139
+ 88
140
+ 89 //受信が終わるまでループ
141
+ 90 while(1){
142
+ 91 char buf[BUF_LEN];
143
+ 92 int read_size;
144
+ 93 read_size = read(s, buf, BUF_LEN);
145
+ 94
146
+ 95 if(read_size > 0) {
147
+ 96 write(1, buf, read_size);
148
+ 97 }
149
+ 98 else{
150
+ 99 break;
151
+ 100 }
152
+ 101 }
153
+ 102
154
+ 103 //ソケットを閉じる
155
+ 104 close(s);
156
+ 105
157
+ 106 return 0;
158
+ 107 }
159
+ 108
160
+ 109
161
+ 110 void parseURL(const char *urlStr, struct URL *url, char **error) {
162
+ 111 char host_path[BUF_LEN];
163
+ 112
164
+ 113 if(strlen(urlStr) > BUF_LEN - 1) {
165
+ 114 *error = "URLが長すぎます。\n";
166
+ 115 return;
167
+ 116 }
168
+ 117
169
+ 118 //http://から始まる文字列で
170
+ 119 //sscanfが成功して
171
+ 120 //http://のあとに何かの文字列が存在するなら
172
+ 121 if(strstr(urlStr, "http://") &&
173
+ 122 sscanf(urlStr, "http://%s", host_path) &&
174
+ 123 strcmp(urlStr, "http://")){
175
+ 124
176
+ 125 char *p = NULL;
177
+ 126
178
+ 127 p = strchr(host_path, '#');
179
+ 128 if(p != NULL){
180
+ 129 strcpy(url->fragment, p);
181
+ 130 *p = '\0';
182
+ 131 }
183
+ 132
184
+ 133 p = strchr(host_path, '?');
185
+ 134 if(p != NULL){
186
+ 135 strcpy(url->query, p);
187
+ 136 *p = '\0';
188
+ 137 }
189
+ 138
190
+ 139 p = strchr(host_path, '/');
191
+ 140 if(p != NULL){
192
+ 141 strcpy(url->path, p);
193
+ 142 *p = '\0';
194
+ 143 }
195
+ 144
196
+ 145 strcpy(url->host, host_path);
197
+ 146
198
+ 147 //ホスト名の部分に":"が含まれていたら
199
+ 148 p = strchr(url1->host, ':');
200
+ 149 if(p != NULL){
201
+ 150 //ポート番号を取得
202
+ 151 url->port = atoi(p + 1);
203
+ 152
204
+ 153 //数字ではない(atoiが失敗)か、0だったら
205
+ 154 //ポート番号は80に決め打ち
206
+ 155 if(url->port <= 0) {
207
+ 156 url->port = 80;
208
+ 157 }
209
+ 158
210
+ 159 //終端文字で空にする
211
+ 160 *p = '\0';
212
+ 161 }
213
+ 162 else{
214
+ 163 url->port = 80;
215
+ 164 }
216
+ 165 }
217
+ 166 else{
218
+ 167 *error = "URLはhttp://host/pathの形式で指定してください。\n";
219
+ 168 return;
220
+ 169 }
221
+ 170 }
222
+ ```
223
+ ###エラーコード
224
+ > $ gcc -o syakyou syakyou.c
225
+ syakyou.c: In function ‘main’:
226
+ syakyou.c:45:21: error: ‘url’ undeclared (first use in this function)
227
+ parseURL(argv[1],&url,&error);
228
+ ^
229
+ syakyou.c:45:21: note: each undeclared identifier is reported only once for each function it appears in
230
+ syakyou.c:58:7: error: ‘struct addrinfo’ has no member named ‘ai_socktyoe’
231
+ hints.ai_socktyoe = AF_INET;
232
+ ^
233
+ syakyou.c: In function ‘parseURL’:
234
+ syakyou.c:148:14: error: ‘url1’ undeclared (first use in this function)
235
+ p = strchr(url1->host, ':');
236
+ ^
237
+
238
+ ###試したこと
239
+ otehon.cはコピペしたテキストプログラム
240
+ syakyou.cは見ながら写したプログラム
241
+ > $ diff syakyou.c otehon.c
242
+
243
+ ###結果
244
+ otehon.cはインデントが空白
245
+ syakyou.cはインデントがタブ
246
+ のため、差分の量が多過ぎて見分けがつかず、お手上げです。

1

2016/07/27 05:54

投稿

dlrowolleh
dlrowolleh

スコア120

title CHANGED
File without changes
body CHANGED
@@ -22,5 +22,10 @@
22
22
  と実行すると、
23
23
  実行したパソコンの自分で指定したディレクトリにHTMLファイルが保存されるというものです。
24
24
 
25
+ これだけでは分からない部分もたくさんあると思います。
26
+
27
+ 自分でも分からないことがたくさんあるので追記などで対応していきます。
28
+
29
+
25
30
  どうかお助けください。
26
31
  よろしくお願いいたします。