爬蟲入門(二)用webmagic爬豆瓣豆列的嘗試(解決403等常見問題)


webmagic學習資料:http://webmagic.io/docs/

原本爬蟲的計划是去扒b站的,結果發現b站是js動態加載的,所以先對豆瓣進行嘗試,練一下手.

整個項目核心是DoubanProcessor的這個類,繼承了webmagic的PageProcessor

其他是自己實現數據庫持久化的.

下面附上DoubanProcessor代碼,具體思路在注釋里,代碼后附上練習中遇到的幾個常見問題.

爬的頁面是:https://www.douban.com/doulist/3907668/

先來看豆列單項:

再來看豆列的html代碼pattern:

 1 <div class="post">
 2       <a href="https://movie.douban.com/subject/6080802/" target="_blank">
 3         <img width="100" src="https://img1.doubanio.com/view/subject/l/public/s4695449.jpg"/>
 4       </a>
 5     </div>
 6     <div class="title">
 7       <a href="https://movie.douban.com/subject/6080802/" target="_blank">
 8         今生只愛你 君だけに愛を Love Forever
 9       </a>
10     </div>
11     
12       <div class="rating">
13           <span class="allstar00"></span>
14           <span>暫無評分</span>
15       </div>
16     <div class="abstract">
17       
18           導演: 細野英延 / 五木田亮一
19             <br />
20           主演: 野村宏伸 / 松下由樹
21             <br />
22           類型: 愛情
23             <br />
24           制片國家/地區: 日本
25             <br />
26           年份: 1991
27     </div>

以下我的DoubanProcessor實現:

 1 public class DoubanProcessor implements PageProcessor{
 2     private Site site = Site.me().setUserAgent("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0").setRetryTimes(3).setSleepTime(1000);
 3 
 4     @Override
 5     public void process(Page page) {
 6         List<String> titles = page.getHtml().xpath("//div[@class='title']/a/text()").all(); //這是匹配標題
 7         List<String> movieUrls = page.getHtml().xpath("//div[@class='post']/a").links().all(); //這是匹配電影url
 8         List<String> ratings = page.getHtml().xpath("//div[@class='rating']/span[@class='rating_nums']/text()").all(); //這是匹配評分
 9         List<String> attrFields = page.getHtml().xpath("//div[@class='abstract']").all(); //這是匹配下方的abstract標簽里的屬性項
10         for (int i = 0; i < titles.size(); i++) { //循環存儲到數據庫
11             DoubanList doubanList=new DoubanList();
12             doubanList.setTitle(titles.get(i));
13             doubanList.setMovieUrl(movieUrls.get(i));
14             doubanList.setRating(ratings.get(i));
15             String[] movieAttrs = attrFields.get(i).split("<br>");
16             if(movieAttrs.length>4) {
17                 doubanList.setDirector(movieAttrs[0].substring(23).trim());
18                 doubanList.setActor(movieAttrs[1].trim());
19                 doubanList.setType(movieAttrs[2].trim());
20                 doubanList.setTime(movieAttrs[4].substring(0, 9).trim());
21             }else {
22                 doubanList.setDirector(attrFields.get(i));
23             }
24             DoubanListDao.save(doubanList);
25         }
26     }
27 
28     @Override
29     public Site getSite() {
30         return site;
31     }
32 
33     public static void main(String[] args) {
34         Spider.create(new DoubanProcessor())
35                 .addUrl("https://www.douban.com/doulist/3907668/")  //設置爬的url
36                 .addPipeline(new ConsolePipeline()) //會output到控制台...在這里並不需要,因為持久化到數據庫了
37                 .thread(5)
38                 .run();
39     }
40 }

下面講講過程中遇到的問題:

  1)403問題:我看了很多博文,發現其實全是互相抄襲.如果嘗試的網站不同,你會發現你很容易遇到403問題.也就是返回status code為403,網站拒絕訪問.其實原因是我們的工具請求沒有攜帶相應的header,所以我在site里調用setUserAgent去設置了UA,至於UA的參數,是從自己的瀏覽器直接抓包復制過來的.於是問題解決了.

  實際上,訪問過快也可能造成403,在一些情況下還需要帶cookie/多個IP爬等等.

  2)匹配多個的問題:看很多文章的時候,基本都是直接page.getHtml().xpath()然后調用get() 或者toString(),實際上看代碼發現,這里只能拿一個數據,而我需要匹配多個,因此要使用all();

Selectable接口注釋:

1   /**
2      * multi string result
3      *
4      * @return multi string result
5      */
6     public List<String> all();

解決了這些問題,其實還有一個問題.

豆瓣的電影格式,會存在沒有導演,主演等信息的情況!!!....所以很坑....所以我添加了數組長度判斷,防止越界,而且實在電影屬性少的時候,就直接存到DB的director字段里.下面是數據庫儲存概括:

下次開始嘗試爬B站!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM