为了分析深圳市所有长租、短租公寓的信息,爬取了某租房公寓网站上深圳区域所有在租公寓信息,网站上租房信息共有258页,每页有20条租房信息(第258页为13条),以下记录了爬取过程以及爬取过程中遇到的问题:

爬取流程:

                            

 

爬取代码:

 1 import requests
 2 from requests.exceptions import RequestException
 3 from pyquery import PyQuery as pq
 4 from bs4 import BeautifulSoup
 5 import pymongo
 6 from config import *
 7 from multiprocessing import Pool
 8 
 9 client = pymongo.MongoClient(MONGO_URL)    # 申明连接对象
10 db = client[MONGO_DB]    # 申明数据库
11 
12 def get_one_page_html(url):    # 获取网站每一页的html
13     headers = {
14         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
15                       "Chrome/85.0.4183.121 Safari/537.36"
16     }
17     try:
18         response = requests.get(url, headers=headers)
19         if response.status_code == 200:
20             return response.text
21         else:
22             return None
23     except RequestException:
24         return None
25 
26 
27 def get_room_url(html):    # 获取当前页面上所有room_info的url
28     doc = pq(html)
29     room_urls = doc(\'.r_lbx .r_lbx_cen .r_lbx_cena a\').items()
30     return room_urls
31 
32 
33 def parser_room_page(room_html):
34     soup = BeautifulSoup(room_html, \'lxml\')
35     title = soup.h1.text
36     price = soup.find(\'div\', {\'class\': \'room-price-sale\'}).text[:-3]
37     x = soup.find_all(\'div\', {\'class\': \'room-list\'})
38     area = x[0].text[7:-11]    # 面积
39     bianhao = x[1].text[4:]
40     house_type = x[2].text.strip()[3:7]    # 户型
41     floor = x[5].text[4:-2]    # 楼层
42     location1 = x[6].find_all(\'a\')[0].text    # 分区
43     location2 = x[6].find_all(\'a\')[1].text
44     location3 = x[6].find_all(\'a\')[2].text
45     subway = x[7].text[4:]
46     addition = soup.find_all(\'div\', {\'class\': \'room-title\'})[0].text
47     yield {
48         \'title\': title,
49         \'price\': price,
50         \'area\': area,
51         \'bianhao\': bianhao,
52         \'house_type\': house_type,
53         \'floor\': floor,
54         \'location1\': location1,
55         \'location2\': location2,
56         \'location3\': location3,
57         \'subway\': subway,
58         \'addition\': addition
59     }
60 
61 
62 def save_to_mongo(result):
63     if db[MONGO_TABLE].insert_one(result):
64         print(\'存储到mongodb成功\', result)
65         return True
66     return False
67 
68 
69 def main(page):
70     url = \'http://www.xxxxx.com/room/sz?page=\' + str(page)    # url就不粘啦,嘻嘻
71     html = get_one_page_html(url)
72     room_urls = get_room_url(html)
73     for room_url in room_urls:
74         room_url_href = room_url.attr(\'href\')
75         room_html = get_one_page_html(room_url_href)
76         if room_html is None:    # 非常重要,否则room_html为None时会报错
77             pass
78         else:
79             results = parser_room_page(room_html)
80             for result in results:
81                 save_to_mongo(result)
82 
83 if __name__ == \'__main__\':
84     pool = Pool()  # 使用多进程提高爬取效率
85     pool.map(main, [i for i in range(1, 258)])

在写爬取代码过程中遇到了两个问题:

(一)在get_room_url(html)函数中,开始是想直接return每个租房信息的room_url,但是return不同于print,函数运行到return时就会结束该函数,这样就只能返回每页第一个租房room_url。解决办法是:return 包含每页所有room_url的generator生成器,在main函数中用for循环遍历,再从每个room_url中获取href,传入到get_one_page_html(room_url_href)中进行解析。

(二)没有写第76行的if语句,我默认get_one_page_html(room_url_href)返回的room_html不为空,因此出现multiprocessing.pool.RemoteTraceback报错:

 

 上图中显示markup为None情况下报错,点击蓝色”F:\ProgramFiles\anaconda3\lib\site-packages\bs4\__init__.py”发现markup为room_html,即部分room_html出现None情况。要解决这个问题,必须让代码跳过room_html is None的情况,因此添加 if 语句解决了这个问题。

最终成功爬取某租房公寓深圳市258页共4755条租房信息,为下一步进行数据分析做准备。

 

 其中单条信息:

 

版权声明:本文为chang2021原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/chang2021/p/14021768.html