前言
最近想爬取一個網站來練習 scrapy 的使用,結果在獲取數據時遇到了問題。明明在瀏覽器可以使用 xpath 代碼定位到指定區域,但是在 Python 里運行起來就是獲取不到文本。我甚至一度以為我獲取文本的方法不對。這里記錄下我的解決過程。
- 雖然可以使用 re 或者 BeautifulSoup 模塊,但是我鐵了心要使用已有的 xpath (css 選擇器內部也是要被轉成 xpath,於是就學/使用這個來提高那么一點點效率)來獲取數據。
分析
這里要獲取一個區域的數據,通過瀏覽器看到的路徑寫了對應的 xpath 代碼,正確運行:
寫好 xpath 代碼:response.xpath("string(//div[@class='co_content8']//span)")
。在 scrapy 跑起來后卻沒有獲取到數據(以后可以學一下 scrapy shell 來測試),將獲取到的 response 寫入文件發現:
- 這里用相對
//span
是因為本站其他網頁有些是有嵌套其他標簽的。
可以發現這里竟然是有個 <td>
標簽的,在瀏覽器上再查看網頁源代碼發現:
原來真的有一個多余的 td 標簽,不太清楚內部獲取文本的邏輯,反正這樣成功導致獲取不到數據了(可能是網站反爬蟲的一個小手段)。
寫代碼測試
瀏覽器雖然解析了 td 為多余的標簽,但是在 xpath 里它卻沒有與瀏覽器一致,以下為我通過 xpath 獲取后 .extract()
的測試結果:
- 使用
"string(//div[@class='co_content8']//span)"
,獲取到的文本為空。 - 使用
"string(//div[@class='co_content8']//span/td)"
,獲取到的文本為空。
- 使用
"string(//div[@class='co_content8']//td)"
,獲取到:
['\xa0']
- 使用
"string(//div[@class='co_content8']//td/*)"
,獲取到:
['\r\n\r\n◎譯\u3000\u3000名\u3000Leap◎片\u3000\u3000名\u3000奪冠/中國女排◎年\u3000\u3000代\u30002020◎產\u3000\u3000地\u3000中國大陸,中國香港◎類\u3000\u3000別\u3000劇情 / 運動◎語\u3000\u3000言\u3000漢語普通話,英語,日語,葡萄牙語◎字\u3000\u3000幕\u3000中文◎上映日期\u30002020-09-25(中國大陸)◎IMDb評分\xa0\xa06.7/10 from 538 users◎豆瓣評分\u30007.3/10 from 255515 users◎文件格式\u3000x264 + aac◎視頻尺寸\u30001920 x 1016◎片\u3000\u3000長\u3000135分鍾◎導\u3000\u3000演\u3000陳可辛 Peter Chan◎編\u3000\u3000劇\u3000張冀 Ji Zhang◎主\u3000\u3000演\u3000鞏俐 Li Gong\u3000\u3000\u3000\u3000\xa0\xa0\u3000黃渤 Bo Huang\u3000\u3000\u3000\u3000\xa0\xa0\u3000吳剛 Gang Wu\u3000\u3000\u3000\u3000\xa0\xa0\u3000彭昱暢 Yuchang Peng\u3000\u3000\u3000\u3000\xa0\xa0\u3000白浪 Lydia Bai\u3000\u3000\u3000\u3000\xa0\xa0\u3000朱婷 Ting Zhu\u3000\u3000\u3000\u3000\xa0\xa0\u3000徐雲麗 Yunli Xu\u3000\u3000\u3000\u3000\xa0\xa0\u3000張常寧 Changning Zhang\u3000\u3000\u3000\u3000\xa0\xa0\u3000姚迪 Di Yao\u3000\u3000\u3000\u3000\xa0\xa0\u3000林莉 Li Lin\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉曉彤 Xiaotong Liu\u3000\u3000\u3000\u3000\xa0\xa0\u3000顏妮 Ni Yan\u3000\u3000\u3000\u3000\xa0\xa0\u3000惠若琪 Ruoqi Hui\u3000\u3000\u3000\u3000\xa0\xa0\u3000丁霞 Xia Ding\u3000\u3000\u3000\u3000\xa0\xa0\u3000袁心玥 Xinyue Yuan\u3000\u3000\u3000\u3000\xa0\xa0\u3000龔翔宇 Xiangyu Gong\u3000\u3000\u3000\u3000\xa0\xa0\u3000李現 Xian Li\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉敏濤 Mintao Liu\u3000\u3000\u3000\u3000\xa0\xa0\u3000陳展 Zhan Chen\u3000\u3000\u3000\u3000\xa0\xa0\u3000羅慧 Hui Luo\u3000\u3000\u3000\u3000\xa0\xa0\u3000毛雯 Wen Mao\u3000\u3000\u3000\u3000\xa0\xa0\u3000李紫微 Ziwei Li\u3000\u3000\u3000\u3000\xa0\xa0\u3000李冬徐 Dongxu Li\u3000\u3000\u3000\u3000\xa0\xa0\u3000馬雪純 Xuechun Ma\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉暢 Chang Liu\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉貞宏 Zhenhong Liu\u3000\u3000\u3000\u3000\xa0\xa0\u3000凌敏 Min Ling\u3000\u3000\u3000\u3000\xa0\xa0\u3000李陽一 Yangyi Li\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉晨曦 Chenxi Liu\u3000\u3000\u3000\u3000\xa0\xa0\u3000邢佳棟 Jiadong Xing\u3000\u3000\u3000\u3000\xa0\xa0\u3000曾春蕾 Chunlei Zeng\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉晏含 Yanhan Liu\u3000\u3000\u3000\u3000\xa0\xa0\u3000王夢潔 Wang Mengjie\u3000\u3000\u3000\u3000\xa0\xa0\u3000鄭益昕 Zheng Yixin\u3000\u3000\u3000\u3000\xa0\xa0\u3000楊涵玉 Hanyu Yang\u3000\u3000\u3000\u3000\xa0\xa0\u3000王媛媛 Yuanyuan Wang\u3000\u3000\u3000\u3000\xa0\xa0\u3000王路加 Lujia Wang\u3000\u3000\u3000\u3000\xa0\xa0\u3000李珊 Shan Li\u3000\u3000\u3000\u3000\xa0\xa0\u3000安家傑 Jiajie An\u3000\u3000\u3000\u3000\xa0\xa0\u3000瑪麗安妮·斯泰因布萊徹 Marianne Steinbrecher\u3000\u3000\u3000\u3000\xa0\xa0\u3000傑奎琳·卡瓦霍 Jaqueline Carvalho\u3000\u3000\u3000\u3000\xa0\xa0\u3000帕烏拉·配奇諾 Paula Pequeno\u3000\u3000\u3000\u3000\xa0\xa0\u3000雅南 Fiona Fu\u3000\u3000\u3000\u3000\xa0\xa0\u3000許文姍 Audrey Hui\u3000\u3000\u3000\u3000\xa0\xa0\u3000宋世雄 Shixiong Song\u3000\u3000\u3000\u3000\xa0\xa0\u3000高野浩幸 Hiroyuki Takano\u3000\u3000\u3000\u3000\xa0\xa0\u3000霍爾·約翰遜 Halle Johnson\u3000\u3000\u3000\u3000\xa0\xa0\u3000孟子旋 Zixuan Meng\u3000\u3000\u3000\u3000\xa0\xa0\u3000李雅楠 Yanan Li\u3000\u3000\u3000\u3000\xa0\xa0\u3000小平花織 Kodaira Kaori\u3000\u3000\u3000\u3000\xa0\xa0\u3000中道瞳 Hitomi Nakamichi\u3000\u3000\u3000\u3000\xa0\xa0\u3000姜倩雯 Qianwen Jiang\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉抒妍 Shuyan Liu\u3000\u3000\u3000\u3000\xa0\xa0\u3000邁克·傑克遜 Mike Jackson\u3000\u3000\u3000\u3000\xa0\xa0\u3000張寒艷 Hanyan Zhang\u3000\u3000\u3000\u3000\xa0\xa0\u3000趙晨璐 Chenlu Zhao\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉桃 Tao Liu\u3000\u3000\u3000\u3000\xa0\xa0\u3000李孟婕 Mengjie Li\u3000\u3000\u3000\u3000\xa0\xa0\u3000田欣 Xin Tian\u3000\u3000\u3000\u3000\xa0\xa0\u3000謝星 Xing Xie\u3000\u3000\u3000\u3000\xa0\xa0\u3000王永強 Yongqiang Wang\u3000\u3000\u3000\u3000\xa0\xa0\u3000杜功海 Gonghai Du◎標\u3000\u3000簽\u3000體育 | 郎平 | 鞏俐 | 運動 | 中國 | 國產電影 | 陳可辛 | 2020◎簡\u3000\u3000介\u3000\u30002008年8月15日,北京奧運會女排比賽,中國VS美國。戴着金絲框眼鏡的郎平(鞏俐 飾)坐在美國隊教練席上,大氣沉穩,目光如電;中國隊教練(黃渤 飾)站在場邊,全神貫注,面帶笑容。中國隊教練望向郎平,目光充滿深意,不斷經過的人影遮蔽了他的視線,中國女排三十余年的沉浮圖景被緩緩打開……◎獲獎情況\u3000\u3000第33屆中國電影金雞獎 (2020)\u3000\u3000最佳故事片\u3000\u3000最佳導演(提名) 陳可辛\u3000\u3000最佳編劇 張冀\u3000\u3000最佳男配角(提名) 吳剛\u3000\u3000最佳攝影 趙曉時\u3000\u3000最佳美術(提名) 孫立\u3000\u3000最佳剪輯(提名) 張一博\u3000\u3000最佳錄音(提名) 黃錚\u3000\u3000\u3000\u3000第6屆豆瓣電影年度榜單 (2019)\u3000\u3000最值得期待的華語電影(提名)【下載地址】 磁力鏈點擊 奪冠.BD.1080p.國語中字.mkv \r\n\r\n\r\n\r\n\r\n\r\n\r\n ']
- 使用
"//div[@class='co_content8']//td/text()"
,獲取到:
['\xa0', '\r\n', '◎譯\u3000\u3000名\u3000Leap', '◎片\u3000\u3000名\u3000奪冠/中國女排', '◎年\u3000\u3000代\u30002020', '◎產\u3000\u3000地\u3000中國大陸,中國香港', '◎類\u3000\u3000別\u3000劇情 / 運動', '◎語\u3000\u3000言\u3000漢語普通話,英語,日語,葡萄牙語', '◎字\u3000\u3000幕\u3000中文', '◎上映日期\u30002020-09-25(中國大陸)', '◎IMDb評分\xa0\xa06.7/10 from 538 users', '◎豆瓣評分\u30007.3/10 from 255515 users', '◎文件格式\u3000x264 + aac', '◎視頻尺寸\u30001920 x 1016', '◎片\u3000\u3000長\u3000135分鍾', '◎導\u3000\u3000演\u3000陳可辛 Peter Chan', '◎編\u3000\u3000劇\u3000張冀 Ji Zhang', '◎主\u3000\u3000演\u3000鞏俐 Li Gong', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000黃渤 Bo Huang', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000吳剛 Gang Wu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000彭昱暢 Yuchang Peng', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000白浪 Lydia Bai', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000朱婷 Ting Zhu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000徐雲麗 Yunli Xu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000張常寧 Changning Zhang', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000姚迪 Di Yao', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000林莉 Li Lin', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉曉彤 Xiaotong Liu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000顏妮 Ni Yan', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000惠若琪 Ruoqi Hui', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000丁霞 Xia Ding', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000袁心玥 Xinyue Yuan', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000龔翔宇 Xiangyu Gong', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000李現 Xian Li', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉敏濤 Mintao Liu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000陳展 Zhan Chen', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000羅慧 Hui Luo', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000毛雯 Wen Mao', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000李紫微 Ziwei Li', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000李冬徐 Dongxu Li', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000馬雪純 Xuechun Ma', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉暢 Chang Liu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉貞宏 Zhenhong Liu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000凌敏 Min Ling', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000李陽一 Yangyi Li', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉晨曦 Chenxi Liu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000邢佳棟 Jiadong Xing', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000曾春蕾 Chunlei Zeng', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉晏含 Yanhan Liu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000王夢潔 Wang Mengjie', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000鄭益昕 Zheng Yixin', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000楊涵玉 Hanyu Yang', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000王媛媛 Yuanyuan Wang', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000王路加 Lujia Wang', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000李珊 Shan Li', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000安家傑 Jiajie An', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000瑪麗安妮·斯泰因布萊徹 Marianne Steinbrecher', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000傑奎琳·卡瓦霍 Jaqueline Carvalho', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000帕烏拉·配奇諾 Paula Pequeno', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000雅南 Fiona Fu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000許文姍 Audrey Hui', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000宋世雄 Shixiong Song', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000高野浩幸 Hiroyuki Takano', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000霍爾·約翰遜 Halle Johnson', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000孟子旋 Zixuan Meng', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000李雅楠 Yanan Li', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000小平花織 Kodaira Kaori', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000中道瞳 Hitomi Nakamichi', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000姜倩雯 Qianwen Jiang', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉抒妍 Shuyan Liu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000邁克·傑克遜 Mike Jackson', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000張寒艷 Hanyan Zhang', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000趙晨璐 Chenlu Zhao', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000劉桃 Tao Liu', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000李孟婕 Mengjie Li', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000田欣 Xin Tian', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000謝星 Xing Xie', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000王永強 Yongqiang Wang', '\u3000\u3000\u3000\u3000\xa0\xa0\u3000杜功海 Gonghai Du', '◎標\u3000\u3000簽\u3000體育 | 郎平 | 鞏俐 | 運動 | 中國 | 國產電影 | 陳可辛 | 2020', '◎簡\u3000\u3000介', '\u3000\u30002008年8月15日,北京奧運會女排比賽,中國VS美國。戴着金絲框眼鏡的郎平(鞏俐 飾)坐在美國隊教練席上,大氣沉穩,目光如電;中國隊教練(黃渤 飾)站在場邊,全神貫注,面帶笑容。中國隊教練望向郎平,目光充滿深意,不斷經過的人影遮蔽了他的視線,中國女排三十余年的沉浮圖景被緩緩打開……', '◎獲獎情況', '\u3000\u3000第33屆中國電影金雞獎 (2020)', '\u3000\u3000最佳故事片', '\u3000\u3000最佳導演(提名) 陳可辛', '\u3000\u3000最佳編劇 張冀', '\u3000\u3000最佳男配角(提名) 吳剛', '\u3000\u3000最佳攝影 趙曉時', '\u3000\u3000最佳美術(提名) 孫立', '\u3000\u3000最佳剪輯(提名) 張一博', '\u3000\u3000最佳錄音(提名) 黃錚', '\u3000\u3000', '\u3000\u3000第6屆豆瓣電影年度榜單 (2019)', '\u3000\u3000最值得期待的華語電影(提名)', ' ', ' ', '\r\n\r\n\r\n\r\n\r\n']
這里可以順帶看出 text()
與 string()
的區別。
最后,需要使用正則來匹配數據。而且因為需要使用到里面的某個標簽的 href 屬性,於是未使用 string()
,僅使用 movie_content = response.xpath("//div[@class='co_content8']//td/*")
獲取 td 標簽下的 html。然后再使用 movie_content.re(r"◎片 名\s+(.*?)<br>")[0]
獲取到電影名稱。
奪冠/中國女排
- 里面的特殊字符:
\xa0
即
,\u3000
為全角空白符。 - 注意到這里使用的是
[0]
而不是普通 re 模塊的[1]
。
其他
在 PyCharm 查看我們的 html 文件時,可以發現這里解析 html 的邏輯與 xpath 的是一致的!因此特殊情況使用這個路徑獲取數據,也是比瀏覽器更為准確的方式。