这边我用的火狐浏览器驱动,因为谷歌浏览器驱动设置IP代理老是失败
我是用的jupyter notebook,所以教大家一个简便办法,将Geckodriver直接上传到你的jupyter notebook里面。点击upload然后,上传。
上传后会出现在下面
-----我们发现上海共有224526套二手房,然而下拉网页以后,发现只显示了100个page ------而且点击100页以后不再显示下一页,这个就尴尬了,链家这边是一页显示30个二手房,100页只有3000个房子,显然与224526套差很多。直接爬是不完全的。 ------为了将数据都拉下来,我们可以点击上面的筛选条件,我们根据区域和有无电梯两个条件来筛选二手房,点击一下看看(为什么选择区域来分,后面会讲) -----显然光限制大区域和有无电梯,二手房有20294套,仍然超过了100页显示3000个的限制,因此我们再改成小区域,我们再加一个“陆家嘴”的小区域限制,发现只有1462个二手房,满足了100页条件,同时点击其他区域也可以发现一个小区域的二手房基本不会超过3000个 我们需要的实际上需要的是点击进去的这个房源的详细信息,观察这个网址发现前面的"https://sh.lianjia.com/chengjiao/"是不变的,只是后面加了一个107101760738号码,估计这个房源编号,显然是没有规律的,因此必须先把所有房源的链接给爬下来
这个url就很有灵性了,“https://sh.lianjia.com/chengjiao/“不变,后面跟了一个小区域拼音缩写"lujiazui”,然后无电梯就是"ie2”,有电梯就是"ie1"(可以自己去点一下有电梯筛选), 本人很懒,不想每个小区域都去打拼音,因此万物皆可selenium 进入浏览器,按F12进入开发者模式,如下图,点击红色框,然后选择我们想要的信息区域(蓝色框),然后下面就会定位到网页的html内容。 我们发现这个"大区域"在这个"div"里面的标签"a"里面的"href"属性中,我们右击–复制–CSS选择器(XPATH),然后复制到代码里面就是,这个就是定位用的".position > dl:nth-child(2) > dd:nth-child(2) > div:nth-child(1) > div:nth-child(1)" ------讲解一下,div,class,a,href是html的一种元素结构,详情请看 html元素结构. 我们在找数据的时候,最好是先定位<div,class="…">结构,然后再到这个结构里面去找文本和链接,由于这里div里面没有class名字,这里就先展示xpath和css_selector定位方法 By.CSS_SELECTOR就是根据CSS选择器定位,同样还有其他定位方式如BY.XPATH; BY.TAG_NAME; BY.CLASS_NAME后面会介绍用法 这里使用wait是因为当你在循环爬取网页数据时,可能会存在延迟而导致数据加载不出来,也自然就无法定位到数据,关于wait的显示等待和隐式等待以及相应的用法可以参考链接:wait用法. wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, “.position > dl:nth-child(2) > dd:nth-child(2) > div:nth-child(1) > div:nth-child(1)”)))这个代码的意思是直到定位到了这个css_selector再进行下一行代码,如果超过10秒还没定位到就报错了。
wait=WebDriverWait(driver,10)##等待页面加载用 #CSS_SELECTOR定位 data=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".position > dl:nth-child(2) > dd:nth-child(2) > div:nth-child(1) > div:nth-child(1)"))) #XPATH定位 data2=wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div[1]/dl[2]/dd/div/div"))) print(data) print(data.text) print(data2.text)输出
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="cec75352-93cf-49f9-8643-12ceb7412874")> '浦东\n闵行\n宝山\n徐汇\n普陀\n杨浦\n长宁\n松江\n嘉定\n黄浦\n静安\n虹口\n青浦\n奉贤\n金山\n崇明\n上海周边' '浦东\n闵行\n宝山\n徐汇\n普陀\n杨浦\n长宁\n松江\n嘉定\n黄浦\n静安\n虹口\n青浦\n奉贤\n金山\n崇明\n上海周边'上面并不是我们想要的内容,因此还需要再细分, 这里不用wait的方法定位元素,是因为前面已经定位到了data,而这个数据是在前面data的基础上获取的,就不需要用wait方法定位,可以find_elements_by_tag_name方法,具体可以参考:链接: selenium 元素定位方法.
print(data.find_elements_by_tag_name('a'))输出,这里面实际上就藏着文本内容和链接
[<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="672cc707-07cd-493d-b93b-e1b842539799")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="6a994423-4c7a-4708-94a9-cf00760dd6bd")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="bbeae6e8-4357-43ff-bfa0-a2505befb182")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="f9e42dfb-d229-4515-8fde-190464016020")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="75292402-3bd9-4a59-9f27-5342a48ecb37")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="fd61e4b6-70a0-4a01-99aa-ff2c070b9eef")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="69622c53-62e7-46db-8a19-4e21becaa5b9")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="28f26ffd-f0ea-4143-a881-4773562809ad")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="de613977-d3d3-4661-be62-2bf13fe8f064")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="655529e8-74c5-4aa8-83d0-9947bc976ede")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="a91af058-af8f-40b1-88f9-d4212b9ce6b7")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="95aeb76c-b4a7-4449-9779-7c778286751a")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="24f1e887-ab68-4b84-9969-fbaccd9e6843")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="e8fdd190-bef6-4282-bbf9-1b5eac2b6476")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="ff1fb103-aee1-4f99-b456-0b2148af454e")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="76960e59-349b-4d46-b08f-821269a82da7")>, <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="9968577e-3da9-4be3-b6c0-9a199e6743cd", element="a381878a-e7c7-4b65-b630-1f046b648896")>]取出链接和对应的大区域
link=[x.get_attribute('href') for x in data.find_elements_by_tag_name('a')] big_area=[x.get_attribute('text') for x in data.find_elements_by_tag_name('a')] url_big_area=list(zip(big_area,link)) print(url_big_area)输出,这里面就有链接和对应的大区域
[('浦东', 'https://sh.lianjia.com/chengjiao/pudong/'), ('闵行', 'https://sh.lianjia.com/chengjiao/minhang/'), ('宝山', 'https://sh.lianjia.com/chengjiao/baoshan/'), ('徐汇', 'https://sh.lianjia.com/chengjiao/xuhui/'), ('普陀', 'https://sh.lianjia.com/chengjiao/putuo/'), ('杨浦', 'https://sh.lianjia.com/chengjiao/yangpu/'), ('长宁', 'https://sh.lianjia.com/chengjiao/changning/'), ('松江', 'https://sh.lianjia.com/chengjiao/songjiang/'), ('嘉定', 'https://sh.lianjia.com/chengjiao/jiading/'), ('黄浦', 'https://sh.lianjia.com/chengjiao/huangpu/'), ('静安', 'https://sh.lianjia.com/chengjiao/jingan/'), ('虹口', 'https://sh.lianjia.com/chengjiao/hongkou/'), ('青浦', 'https://sh.lianjia.com/chengjiao/qingpu/'), ('奉贤', 'https://sh.lianjia.com/chengjiao/fengxian/'), ('金山', 'https://sh.lianjia.com/chengjiao/jinshan/'), ('崇明', 'https://sh.lianjia.com/chengjiao/chongming/'), ('上海周边', 'https://sh.lianjia.com/chengjiao/shanghaizhoubian/')]接下来就是遍历大区域,取出小区域,然后将小区域和"ie2"和"ie1"链接起来即可 这里没有设置无头模式和不加载图片模式,是为了让初学者可以对着浏览器观看数据是怎么爬取下来的,代码在运行的时候,会发现浏览器会 自动输入大区域链接,然后爬数据
firefox_options = Options() firefox_options.add_argument('--proxy-server=http://'+random.choice(ip_list))###更换IP地址 driver = webdriver.Firefox(options=firefox_options) url_small_area=[] i=1 for big_area,url in url_big_area: try: print('正在执行第'+str(i)+'个大区域') driver.get(url) wait=WebDriverWait(driver,10) data3=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".position > dl:nth-child(2) > dd:nth-child(2) > div:nth-child(1) > div:nth-child(2)"))) link1=[(x.get_attribute('href')+'ie1',x.text,big_area) for x in data3.find_elements_by_tag_name('a')] ###有电梯二手房链接 link2=[(x.get_attribute('href') +'ie2',x.text,big_area)for x in data3.find_elements_by_tag_name('a')] ###无电梯二手房链接 url_small_are.extend(link1) url_small_are.extend(link2) i=i+1 except: print(url)我们分析一下这条核心语句,"x.get_attribute(‘href’)+‘ie1’"是获取有电梯二手房链接,x.text是获取小区域,big_area是刚刚爬取的大区域内容,然后zip到一起
link1=[(x.get_attribute('href')+'ie1',x.text,big_area) for x in data2.find_elements_by_tag_name('a')] ###有电梯二手房链接这样就爬完了所有小区域链接,然后我们看看前10条
pd.DataFrame(data=url_small_area[0:10],columns=['链接','小区域','大区域'])输出,一共445个小区域
链接 小区域 大区域 https://sh.lianjia.com/chengjiao/beicai/ie1 北蔡 浦东 https://sh.lianjia.com/chengjiao/biyun/ie1 碧云 浦东 https://sh.lianjia.com/chengjiao/caolu/ie1 曹路 浦东 https://sh.lianjia.com/chengjiao/chuansha/ie1 川沙 浦东 https://sh.lianjia.com/chengjiao/datuanzhen/ie1 大团镇 浦东 https://sh.lianjia.com/chengjiao/gaodong/ie1 高东 浦东 https://sh.lianjia.com/chengjiao/gaohang/ie1 高行 浦东 https://sh.lianjia.com/chengjiao/geqing/ie1 合庆 浦东 https://sh.lianjia.com/chengjiao/hangtou/ie1 航头 浦东 https://sh.lianjia.com/chengjiao/huamu/ie1 花木 浦东 https://sh.lianjia.com/chengjiao/huinan/ie1 惠南 浦东 https://sh.lianjia.com/chengjiao/jinqiao/ie1 金桥 浦东先用第一个小区域链接来分析网页
firefox_options = Options() firefox_options.add_argument('--proxy-server=http://'+random.choice(ip_list))###更换IP地址 driver = webdriver.Firefox(options=firefox_options) url='https://sh.lianjia.com/chengjiao/beicai/ie1' driver.get(url)–回到浏览器,按F12进入开发者模式,定位到蓝色框 我们发现所有二手房源的链接在"ul class=‘listContent’"里面,然后每一个二手房源链接都在"li"结构里面的"div class='title"里面的"a"标签的href属性里面。 那么第一步先获取listcontent的内容给data,然后对data进行find_elements,注意区分find_element和find_elements,前者是只定位第一个数据,后者是找出所有数据,返回的是一个列表
data=wait1.until(EC.presence_of_element_located((By.CLASS_NAME,'listContent'))) data1=data.find_elements_by_class_name('title') link=[x.find_element_by_tag_name('a').get_attribute('href') for x in data1] print(link)输出
['https://sh.lianjia.com/chengjiao/107101937208.html', 'https://sh.lianjia.com/chengjiao/107102668786.html', 'https://sh.lianjia.com/chengjiao/107102670241.html', 'https://sh.lianjia.com/chengjiao/107102564549.html', 'https://sh.lianjia.com/chengjiao/107102390369.html', 'https://sh.lianjia.com/chengjiao/107101993443.html', 'https://sh.lianjia.com/chengjiao/107102591914.html', 'https://sh.lianjia.com/chengjiao/107102452987.html', 'https://sh.lianjia.com/chengjiao/107102497050.html', 'https://sh.lianjia.com/chengjiao/107102263629.html', 'https://sh.lianjia.com/chengjiao/107102576678.html', 'https://sh.lianjia.com/chengjiao/107101931522.html', 'https://sh.lianjia.com/chengjiao/107102505370.html', 'https://sh.lianjia.com/chengjiao/107102503932.html', 'https://sh.lianjia.com/chengjiao/107102526821.html', 'https://sh.lianjia.com/chengjiao/107102640536.html', 'https://sh.lianjia.com/chengjiao/107102474635.html', 'https://sh.lianjia.com/chengjiao/107101894602.html', 'https://sh.lianjia.com/chengjiao/107102300738.html', 'https://sh.lianjia.com/chengjiao/107102487816.html', 'https://sh.lianjia.com/chengjiao/107102553232.html', 'https://sh.lianjia.com/chengjiao/107102609621.html', 'https://sh.lianjia.com/chengjiao/107102609441.html', 'https://sh.lianjia.com/chengjiao/107102412595.html', 'https://sh.lianjia.com/chengjiao/107101647923.html', 'https://sh.lianjia.com/chengjiao/107102093342.html', 'https://sh.lianjia.com/chengjiao/107101671015.html', 'https://sh.lianjia.com/chengjiao/107102538554.html', 'https://sh.lianjia.com/chengjiao/107102485376.html', 'https://sh.lianjia.com/chengjiao/107102454160.html']上面就是真正我们要的二手房的链接,但是上面爬的只是一页的30个房源,而我们又无法确定每个小区域有多少个页数,那么怎么才能把所有(82个页面)链接都爬下来的。 这需要用到定位"下一页 "链接的方法了, 思路就是,使用BY.LINK_TEXK方法定位"下一页"这个翻页按钮,然后写try语句循环click()这个按钮,直到定位不到"下一页"报错以后,就是最后一页了,然后break跳出循环。 firefox_options.add_argument(’–headless’)这个无头模式建议初学者去掉,先跑一小会程序,对着浏览器观察一下爬虫的运行过程,熟悉以后可以再加上让它在后台重新跑
url_small_area=pd.DataFrame(data=url_small_area,columns=['链接','小区域','大区域']) url_all=[] i=1 ran=[random.randint(1,len(url_small_are)) for i in range(int((len(url_small_are)+1)/25))]##这里是每隔25个就随机选择一个ip地址,防止被封 firefox_options = Options() ##firefox_options.add_argument('--headless')###无头模式 firefox_options.add_argument('--disable-gpu')-##--不使用gpu,主要阻止图片加载 firefox_options.set_preference('permissions.default.image', 2)##---不加载图片 firefox_options.add_argument('--proxy-server=http://'+random.choice(ip_list))###更换IP地址 driver = webdriver.Firefox(options=firefox_options) for index,row in url_small_are.iterrows(): url=row['链接'] smallarea=row['小区域'] bigarea=row['大区域'] print('------正在执行第'+str(i)+'个房源--',end='') start=time.clock() driver.get(url) wait=WebDriverWait(driver,5) while True: try: data=wait.until(EC.presence_of_element_located((By.CLASS_NAME,'listContent'))) link=[(x.find_element_by_tag_name('a').get_attribute('href'),smallarea,bigarea) for x in data.find_elements_by_class_name('title')] pd.DataFrame(link).to_csv('C:/Users/Jax/Desktop/链接_链家_2.csv',mode='a',header=False,encoding='utf_8_sig') url_all.extend(link) next_page=wait.until(EC.presence_of_element_located((By.LINK_TEXT,'下一页'))) next_page.click() except: print('------完成时间------',end='') break #下面这段代码是用来判断是否进行ip地址的更换,如果满足条件就关闭浏览器,然后重新打开浏览器,设置新的IP地址 if i in ran: driver.close() firefox_options = Options() firefox_options.add_argument('--headless')###无头模式 firefox_options.add_argument('--disable-gpu')-##--不使用gpu,主要阻止图片加载 firefox_options.set_preference('permissions.default.image', 2)##---不加载图片 firefox_options.add_argument('--proxy-server=http://'+random.choice(ip_list))###更换IP地址 driver = webdriver.Firefox(options=firefox_options) i=i+1 else: i=i+1 end=time.clock() ###这里加一个用来中断代码的csv pd.DataFrame([]).to_csv('C:/Users/Jax/Desktop/中断.csv',mode='a',header=False,encoding='utf_8_sig') print(round((end-start),1))这里加了一个to_csv('C:/Users/Jax/Desktop/中断.csv…)的原因是,当程序运行一定时间后,如果你想看看运行情况而中断程序时,在jupyter notebook里面点击中断程序会卡死,但是我加一个中断的csv就可以通过打开这个中断文件使得程序通过报错来停止运行,而非强制中断。
上面就爬完了所有的二手房房源链接,并存在了本地的CSV文件里面,接下来的数据内容就很简单了。
1.标题数据 进入浏览器,F12开发者模式,定位后发现标题数据在"div class=wrapper"里面,因此我们可以使用多种方法定位,
title=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".house-title > div:nth-child(1)"))).text print(wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".house-title > div:nth-child(1)"))).text)### css_selector定位方法 print(wait.until(EC.presence_of_element_located((By.CLASS_NAME, "wrapper"))).text)### class_name定位方法 print(wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/div[4]/div"))).text)### xpath定位方法输出
玉兰小区 2室1厅 69.84平米2020.06.08 成交 玉兰小区 2室1厅 69.84平米2020.06.08 成交 玉兰小区 2室1厅 69.84平米2020.06.08 成交2. 价格,带看次数等信息 定位后发现总价和单位面积价格在"div class=price"里面,而带看次数,成交周期,挂牌价格等数据在"div class=msg"里面,因此分别取出来; 如果为了设置总价和单位面积价格为两个字段,可以发现总价在"div class=price"里面的"span"标签里面,而单位面积价格在“b”标签里面。
price=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".price"))) price_total=price.find_element_by_tag_name('span').text price_per=price.find_element_by_tag_name('b').text print(price_total) print(price_per)输出
312万 343773.挂牌价格、成交周期、调价次数、带看次数、…浏览次数信息
我们发现每一个字段的数据在"div class=msg"结构里面的"span"标签里面,但是真正的数据是在"span"标签里面的"label"里面
info1=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div.msg:nth-child(3)"))) sup1=[x.text for x in info1.find_elements_by_tag_name('label')] sup1输出
['320', '39', '1', '52', '24', '603']4.房屋基本信息数据 定位发现第一块基本信息数据在"div class=content"结构里面,而每一个房屋户型、建筑面积等字段在"li"里面,而且我们发现真正的数据"2室1厅1厨1卫"没有标签,只能先取出"li"里面的text,然后我们发现所有的字段列名都是四个字,这个就很舒服了,用字符串索引方式即可。
info2=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".base > div:nth-child(2)"))) sup2=[x.text[4:] for x in info2.find_elements_by_tag_name('li')] sup2输出
['3室2厅1厨1卫', '低楼层(共14层)', '90.76㎡', '平层', '暂无数据', '板楼', '南', '2011', '精装', '钢混结构', '', '一梯两户', '有']后面的数据内容就不再一一介绍了, 都是重复的定位和取数据,直接给代码了
info3=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".transaction > div:nth-child(2)"))) sup3=[x.text[4:] for x in info3.find_elements_by_tag_name('li')] print(sup3) sup4_1=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".record_detail"))).text sup4_2=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".record_price"))).text sup4=sup4_2+','+sup4_1 print(sup4) info5=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".xiaoqu_main")))## sup5=[x.text for x in X.find_elements_by_tag_name('span')] print(sup5) info6=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".showbasemore")))## sup6=[x.text for x in info6.find_elements_by_class_name('content')] print(sup6) info7=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".bd")))## sup7=[x.text for x in info7.find_elements_by_tag_name('span')] print(sup7)输出
['107102439850', '商品房', '2020-04-25', '普通住宅', '暂无数据', '共有'] '312万,单价34377元/平,2020-06成交' ['33620 元/㎡', '2006年', '板楼', '105栋', '暂无数据', '18套在售二手房', '13套出租房源', '2020-06-19'] ['此房满两年,楼层好,视野开阔,楼间距大,小区环境好 房子新', '维罗纳贵都位于松江新城和老城的交汇处,既有新城的优美环境,又有老城的生活配套及氛围。小区为地中海风情,意大利建筑风格,由多层(带电梯)、小高层公寓组成,绿化采用主团分布和集中绿化两种方式,保证户户有景的同时,使小区拥有集中的公共的绿化休闲', '松江繁华地段,荣乐路,仓汇路,玉树路商铺,金融,餐饮,银行。。一条街,东边大润发,飞航,沃尔玛,西边家乐福购物广场,小区出门菜市场,玉树路,三辰菜市场,人民医院,妇保医院,交通大 學附属医院,华 亭 幼 稚 园, 对 外 经 贸', '小区出门有轨电车,距沪昆高速,九号线体育站不到2公里,14路,34路,松卫线,松亭石专线,有轨电车已经开通,出行方便,交通网络四通八达'] ['小区刚开盘买进,房子属于南北2房加1书房(储藏室或者小孩房),位于4楼,房型“正气”南北通透,客厅较大,采光好,客厅阳台面积大且望下去就是花园,景色优美。主卧房间窗户大,躺在床上都可一览楼下花园美景。2017年小孩结婚才装修,买来拎包入住即可。(祖孙三代居住且考虑二胎打算置换爱房)', '小区2011年建造,属于次新小区,小区风格属于欧式洋房,绿化率高,环境整洁,景色优美。小区西门口有幼儿园,2个菜品超市,1个农贸市场,小区还配备了3个小孩游乐场,1个青年健身跑道,3-5套老年人健身器材、2-3个广场舞场所等等等等']直接给代码了,url_all是前面的我们爬取好的链接,存在了本地的csv里面 1.导入库
from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.webdriver.firefox.options import Options from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素 import time import random import pandas as pd2.设置IP池、浏览器设置以及获取网页
ip_list=[ #ip存放地址 '118.70.144.77:3128', '113.200.105.45:8080', '116.207.131.19:8080', '119.133.16.247:4216', '113.59.99.138:8910' ] user_agent_list=[ 'Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0)', 'Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.0;Trident/4.0)', 'Mozilla/4.0(compatible;MSIE7.0;WindowsNT6.0)', 'Opera/9.80(WindowsNT6.1;U;en)Presto/2.8.131Version/11.11', 'Mozilla/5.0(WindowsNT6.1;rv:2.0.1)Gecko/20100101Firefox/4.0.1', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)', 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.3.4000 Chrome/30.0.1599.101 Safari/537.36', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.0.3214.0 Safari/537.36', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0' ] header={ 'User-Agent':random.choice(user_agent_list)} ip={'http':random.choice(ip_list)} url_all=pd.read_csv('C:/Users/Jax/Desktop/链接_链家_2.csv') firefox_options = Options() firefox_options.add_argument('--headless')###无头模式 firefox_options.add_argument('--disable-gpu')-##--不使用gpu,主要阻止图片加载 firefox_options.set_preference('permissions.default.image', 2)##---不加载图片 firefox_options.add_argument('--proxy-server=http://'+random.choice(ip_list))###更换IP地址 driver = webdriver.Firefox(options=firefox_options) content=[] i=1 ran=[random.randint(1,len(url_all_data)) for i in range(int((len(url_all_data)+1)/25))] for index,row in url_all.iterrows(): try: temp=[] url=row['链接'] smallarea=[row['小区域']] bigarea=[row['大区域']] print('------正在执行第'+str(i)+'个房源--',end='') start=time.clock() driver.get(url) wait=WebDriverWait(driver,3) except: print('异常在链接'+url) continue try: title=[wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".house-title > div:nth-child(1)"))).text] except: print('异常在title') title=[] try: price=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".price"))) price_total=[price.find_element_by_tag_name('span').text] price_per=[price.find_element_by_tag_name('b').text] except: print('异常在price') price_total=[] price_per=[] try: info1=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div.msg:nth-child(3)"))) sup1=[x.text for x in info1.find_elements_by_tag_name('label')] info2=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".base > div:nth-child(2)"))) sup2=[x.text[4:] for x in info2.find_elements_by_tag_name('li')] info3=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".transaction > div:nth-child(2)"))) sup3=[x.text[4:] for x in info3.find_elements_by_tag_name('li')] except: print('异常在info1') sup1=[] sup2=[] sup3=[] try: sup4_1=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".record_detail"))).text sup4_2=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".record_price"))).text sup4=[sup4_2+','+sup4_1] except: sup4=[] print('异常在sup4') try: info5=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".xiaoqu_main")))## sup5=[x.text for x in info5.find_elements_by_tag_name('span')] sup5.append(datetime.datetime.now().strftime('%Y-%m-%d')) except: sup5=[] print('异常在sup5') try: wait1=WebDriverWait(driver,1)##这里重新设置一个wait1等待1秒的原因是,很多二手房没有sup6,sup7信息,如果你设置等待5秒,意义不大,会浪费时间 info6=wait1.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".showbasemore")))## sup6=[x.text for x in info6.find_elements_by_class_name('content')] except: sup6=[] print('异常在sup6') try: wait1=WebDriverWait(driver,1) info7=wait1.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".bd")))## sup7=[x.text for x in info7.find_elements_by_tag_name('span')] except: sup7=[] print('异常在sup7') temp.extend([url]+smallarea+bigarea+title+price_total+price_per+sup1+sup2+sup3+sup4+sup5+sup6+sup7) content.append(temp) pd.DataFrame([temp]).to_csv('C:/Users/EDZ/Desktop/链家_数据4.csv',mode='a',header=False,encoding='utf_8_sig') if i in ran: driver.close() firefox_options = Options() firefox_options.add_argument('--headless')###无头模式 firefox_options.add_argument('--disable-gpu')-##--不使用gpu,主要阻止图片加载 firefox_options.set_preference('permissions.default.image', 2)##---不加载图片 firefox_options.add_argument('--proxy-server=http://'+random.choice(ip_list))###更换IP地址 driver = webdriver.Firefox(options=firefox_options) i=i+1 else: i=i+1 end=time.clock() pd.DataFrame([]).to_csv('C:/Users/EDZ/Desktop/中断_数据.csv',mode='a',header=False,encoding='utf_8_sig') print(round((end-start),1))最终电脑跑下来,如果二手房数据都全则1.6秒一条数据,如果二手房没有sup6或者7,就大概2.5秒一条数据。