我正在做一个网页抓取项目。第一个下拉菜单有大约 800 个选项,第二个下拉菜单有 20 多个值。这样做的过程非常缓慢。所以我尝试使用多处理,希望它可以稍微加快这个过程。但是,我收到了无法解决的错误消息。
我的代码是:
def create_df(city_var, year_var):
city = Select(driver.find_element_by_css_selector("select[id*='Main_csCity_ddlEntity1']"))
city.select_by_visible_text(city_var)
year = Select(driver.find_element_by_css_selector("select[id*='Main_csCity_ddlYear1']"))
year.select_by_visible_text(year_var)
try:
driver.find_element_by_xpath('//input[@type="submit"]').click()
except Exception as e:
time.sleep(1)
driver.find_element_by_xpath('//input[@type="submit"]').click()
print('something wrong:'+city_var+year_var)
html = driver.page_source
soup = BeautifulSoup(html, "lxml")
try:
small_header = soup.find_all("div",{"class":"ResultsHeader"})
ret_list = []
for idx, span in enumerate(small_header[0].find_all("span")):
if idx in [1,3,5,7]:
ret_list.append(span.contents[0])
except:
print(city_var+year_var)
try:
second_header = soup.find_all("tr",{"class":re.compile('Detail.*')})
ret_list2 = []
for idx, content in enumerate(second_header):
if len(content.contents) == 3:
ret_list2.append([content.contents[1].contents[0], '', '', ''])
elif len(content.contents) == 7:
sublist = []
for idx2 in range(5):
if idx2 == 1:
continue
sublist.append(content.contents[idx2+1].contents[0])
ret_list2.append(sublist)
else:
print('WRONG')
except:
print(city_var+year_var)
ret_list3 = ret_list2[1:]
ret_list4 = [ret_list+sub for sub in ret_list3]
return pd.DataFrame(ret_list4)
list_of_city_year = [[x,y] for x in cities1 for y in years]
def return_df(list1):
df = pd.DataFrame()
c = list1[0]
y = list1[1]
df = df.append(create_df(c, y))
return df
with Pool(5) as p:
records = p.map(return_df, list_of_city_year[:100])
错误消息很长。它也输出了之前的结果,所以我只放了错误部分:
也许编码错误回溯(最近的调用( 最后( 在 (( 中 1 与池 (5( 作为 p: ----> 2 条记录 = p.map(return_df, list_of_city_year[:100](
~/anaconda3/lib/python3.6/multiprocessing/pool.py in map(self, func, 可迭代,块大小( 返回的列表中为 264。 265 ''' --> 266 返回self._map_async(func, iterable, mapstar, chunksize(.get(( 267 268 def starmap(self, func, iterable, chunksize=None(:
~/anaconda3/lib/python3.6/multiprocessing/pool.py in get(self, 超时( 642 返回self._value 643 其他: --> 644 提高self._value 645 646 def _set(self, i, obj(:
也许编码错误:发送结果时出错:"[ 0 1 2
3 4 5 \ ..... ....]'.原因:"递归错误("超出最大递归深度 同时调用 Python 对象',('
如果您对如何改进代码以使其更高效有任何建议,请在下面发布。
这样的MaybeEncodingError
主要是因为你忘记使用if __name__ == '__main__':
尝试在Windows上创建工作版本时,我遇到了一条奇怪的重复错误消息。
Attempt to start a new process before the current process
has finished its bootstrapping phase.
This probably means that you are on Windows and you have
forgotten to use the proper idiom in the main module:
if __name__ == '__main__':
从字面上引用我得到的评论,因为它是不言自明的:
Windows上的错误是因为每个进程都会生成一个新的Python进程来解释Python文件等,因此"if主块"之外的所有内容都会再次执行">
因此,要具有可移植性,您必须在运行此模块时使用if __name__=='__main__'
:
import multiprocessing as mp
from multiprocessing import Pool, freeze_support
if __name__ == '__main__': #you need this in windows
freeze_support()
main()